Baz*_*zzz 36 c# generics reflection activator
我有一个泛型类型Store<T>,用于Activator创建这种类型的实例.现在,在使用Activator之后,我可以将结果对象的类型转换object回实例化类型吗?我知道我用来实例化泛型的类型.请参阅以下代码:
class Store<T> where T : IStorable
{}
class Beer : IStorable
{}
class BeerStore : Store<Beer>
{}
Type storeType = someObjectThatImplementsIStorable.GetType();
Type classType = typeof(Store<>);
Type[] typeParams = new Type[] { storeType };
Type constructedType = classType.MakeGenericType(typeParams);
object x = Activator.CreateInstance(constructedType, new object[] { someParameter });
Run Code Online (Sandbox Code Playgroud)
我想做的是这样的事情:
var store = (Store<typeof(objectThatImplementsIStorable)>)x;
Run Code Online (Sandbox Code Playgroud)
但由于显而易见的原因,这不起作用.作为替代方案,我试过:
var store = (Store<IStorable>)x;
Run Code Online (Sandbox Code Playgroud)
这可能在我看来有效,但给出了一个InvalidCastException.
如何再次访问Store<T>对象中我知道的方法x?
das*_*ght 30
由于实际类型T仅通过反射可用,因此您还需要访问Store<T>反射方法:
Type constructedType = classType.MakeGenericType(typeParams);
object x = Activator.CreateInstance(constructedType, new object[] { someParameter });
var method = constructedType.GetMethod("MyMethodTakingT");
var res = method.Invoke(x, new object[] {someObjectThatImplementsStorable});
Run Code Online (Sandbox Code Playgroud)
编辑您还可以定义一个IStore不使用泛型的附加接口,而是使用IStorable:
interface IStore {
int CountItems(IStorable item);
}
class Store<T> : IStore where T : IStorable {
int CountItems(IStorable item) {
return count;
}
}
Run Code Online (Sandbox Code Playgroud)
您Store<T>将保持通用,但您可以CountItems通过转换来访问它IStore:
var x = (IStore)Activator.CreateInstance(constructedType, new object[] { someParameter });
var count = x.CountItems((IStorable)someObjectThatImplementsStorable);
Run Code Online (Sandbox Code Playgroud)
你不能把它包起来吗?
就像是
public Store<T> IConstructStore<T>(T item) where T : IStorable
{
return Activator.CreateInstance(typeof(Store<T>), new object[] { someParameter }) as Store<T>;
}
Run Code Online (Sandbox Code Playgroud)
或者我错过了你想要做什么?
IE
class Program
{
static void Main(string[] args)
{
Beer b = new Beer();
var beerStore = IConstructStore(b);
Console.WriteLine(beerStore.test);
Console.WriteLine(beerStore.GetType().ToString());
}
public static Store<T> IConstructStore<T>(T item) where T : IStorable
{
return Activator.CreateInstance(typeof(Store<T>), new object[] { }) as Store<T>;
}
}
interface IStorable { }
class Store<T> where T : IStorable
{
public int test = 1;
}
class Beer : IStorable
{ }
Run Code Online (Sandbox Code Playgroud)
印刷
1
ConsoleApp1.Store'1[ConsoleApp1.Beer]
Run Code Online (Sandbox Code Playgroud)