C# Generics methods and returning a object of a parameterized type created in the method from xml

10,231

Solution 1

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();
}

Solution 2

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.

Share:
10,231
theringostarrs
Author by

theringostarrs

Updated on June 21, 2022

Comments

  • theringostarrs
    theringostarrs almost 2 years

    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?

  • Marc Gravell
    Marc Gravell almost 15 years
    Nice edit - I've seen a lot of people confused by the (far less common) open-type syntax.
  • Randolpho
    Randolpho almost 15 years
    Odds are you'd have to replace typeof(string) with GetType(typeName);
  • BFree
    BFree almost 15 years
    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...
  • Josh
    Josh almost 15 years
    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.
  • Coryza
    Coryza almost 15 years
    @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.
  • theringostarrs
    theringostarrs almost 15 years
    Thank you. I am using what you suggested with a generic Foo implementing non-generic IFoo.