views:

1738

answers:

2

Hi,

I have a method where I would like to return an object instance of parameterized type T ie. Foo<T>.

The type T is instantiated within the method using GetType(), from a string element in an XML file. Since neither the class or method knows about it before it is created, I cant parameterize either.

Is there a way I can return an object of type Foo<T> from the non-generic method?

EDIT: That is a method signature such as:

 public Foo<T> getFooFromXml(string name) {

where the type is created inside, and the method and class are both non-generic?

+7  A: 

Yeah, basically you have to get the open generic type and create a closed generic type.

Type openType = typeof(Foo<>);
Type closedType = openType.MakeGenericType(typeof(string));

return Activator.CreateInstance(closedType); // returns a new Foo<string>

EDIT: Note that I used typeof(Foo<>) above, I intentionally left the angle brackets empty.

Josh Einstein
Nice edit - I've seen a *lot* of people confused by the (far less common) open-type syntax.
Marc Gravell
Odds are you'd have to replace typeof(string) with GetType(typeName);
Randolpho
Activator.CreateInstance returns an object. How would you then cast it further to a Foo and be able to use it as a Foo? The only way I can think of would be to have to use reflection to get the Methods / Properties you want from the object, and take it from there. I don't see any other way...
BFree
Well by definition, Foo<T> is not usable in any strong typed way. If you only know the T at runtime then you have to use it in a dynamic way using either reflection or a late bound capable language like VB.NET or C# 4.0.Generally if you want to use it in this way you'd make Foo<T> implement IFoo that uses Object everywhere T is used in the generic type.
Josh Einstein
@BFree - yes, you can't cast it to an open generic (like Foo<>), so if you want to call anything on it, you'll have to use reflection (or .NET 4.0 dynamic stuff) here. Of course, your caller may have enough info to allow them to cast it to a Foo<string> and call stuff on it.
Jonathan
A: 

In response to your edit:

That method signature isn't valid anyway. You need to know T at compile time in order to return Foo from a method. Consider my suggestion in the comments on my last answer where you would have a separate interface IFoo that Foo implements.

class Foo<T> : IFoo {

   public T DoSomething() {
       ...
   }

   object IFoo.DoSomething() {
      return DoSomething();
   }

}

interface IFoo {
   object DoSomething();
}
Josh Einstein
Thank you. I am using what you suggested with a generic Foo implementing non-generic IFoo.
theringostarrs