Reputation: 4190
I have class like this:
public ClassA<T> where T : class{
...
}
Now I need to to create an object of ClassA in the constructor of ClassB:
public ClassB{
public ClassA<?> objA;
public ClassB(string TypeInfo){
objA = new ClassA<?>(); // Suppose TypeInfo = 'ClassC', and the '?'
// Should be derived from TypeInfo
}
...
}
I don't know what to replace '?' for, since the type can only be known at runtime... any ideas?
Upvotes: 1
Views: 577
Reputation: 4134
The closest to determining and creating the generic type at runtime that you'll probably get (using a string that represents the type name) is instantiating it like this.
public class ClassB
{
public ClassB(string typeInfo)
{
var typeOfT = Type.GetType(typeInfo);
var type = typeof(ClassA<>).MakeGenericType(typeOfT);
var instance = Activator.CreateInstance(type);
}
}
Exposing that directly through a public field will not be doable unless you mark your field as dynamic, because otherwise it will need that generic type information up front.
public dynamic objA;
Also, the string that represents the type must be qualified enough so that it can be located without ambiguity by Type.GetType()
. For example, SomeNamespace.ClassC
instead of ClassC
.
Upvotes: 10
Reputation: 2566
There is no reason to use generics for the types not known at compile time, because generics is used only for the KNOWN types, which means you can always make a substitution of a generic parameter with a type.
The only matching type in the questioned situation is object
type which is a base class for the all object types, and is always known to the compiler.
public ClassB{
public ClassA<object> objA;
public ClassB(string TypeInfo){
objA = new ClassA<object>();
}
...
}
About your question...
The only way to use a type not known at compile time is resolve the type at run time, make the ClassB generic, and use ILGenerator() for the generic class A to instantiate of construction of that class at the run-time.
public ClassB<T>{
public ClassA<T> objA;
public ClassB(){
objA = new ClassA<T>();
}
...
}
Upvotes: -1
Reputation: 13077
Since objA is part of the definition of ClassB, ClassB will have to have to have a type parameter if ClassA has a type parameter, i.e.
public ClassB<T>
{
public ClassA<T> objA
...
}
If the type of objA is not known at compile time it will have to be of type Object
or a non-generic base or interface. There's no middle ground.
Upvotes: 0
Reputation: 22760
use object o = Activator.CreateInstance(constructed);
this came from MSDN http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
edit
we use it in extension methods like;
public static object DefaultValue(this Type targetType) { return targetType.IsValueType ? Activator.CreateInstance(targetType) : null; }
It's not a huge stretch to make it work with generics
Upvotes: 0