C# Generics methods and returning a object of a parameterized type created in the method from xml
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.
theringostarrs
Updated on June 21, 2022Comments
-
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 almost 15 yearsNice edit - I've seen a lot of people confused by the (far less common) open-type syntax.
-
Randolpho almost 15 yearsOdds are you'd have to replace typeof(string) with GetType(typeName);
-
BFree almost 15 yearsActivator.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 almost 15 yearsWell 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 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 almost 15 yearsThank you. I am using what you suggested with a generic Foo implementing non-generic IFoo.