如何使用激活创建一个通用类型的实例和铸造回的类型? [英] How to use Activator to create an instance of a generic Type and casting it back to that type?

查看:163
本文介绍了如何使用激活创建一个通用类型的实例和铸造回的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个泛型类型商店< T> ,并使用激活来使这种类型的实例。现在怎么样,使用激活后,可我投类型的对象产生对象回实例化的类型?我知道,我用实例化泛型类型。请看下面的代码:

I have a generic type Store<T> and use Activator to make an instance of this type. Now how, after using the Activator, can I cast the resulted object of type object back to the instantiated type? I know the type that I used to instantiate the generic. Please see the following code:

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



我想什么做的是这样的:

What I would like to do is something like this:

var store = (Store<typeof(objectThatImplementsIStorable)>)x;



但是,这并不显而易见的原因的工作。作为一种替代方法我试过:

but that doesn't work for obvious reasons. As an alternative I tried:

var store = (Store<IStorable>)x;



这可能在我看来,可能是工作,但给出了一个 InvalidCastException的

我如何再次访问商店< T>我知道是方法在对象 X

How do I get access again to the Store<T> methods that I know are in the object x?

推荐答案

由于实际类型 T 是提供给您只能通过反射,你需要访问的商店和LT方法; T> 通过反射,以及:

Since the actual type T is available to you only through reflection, you would need to access methods of Store<T> through reflection as well:

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

修改您也可以定义一个额外的网​​上商店界面不使用仿制药,并使用 IStorable 而不是:

EDIT You could also define an additional IStore interface that does not use generics, and uses IStorable instead:

interface IStore {
    int CountItems(IStorable item);
}
class Store<T> : IStore where T : IStorable {
    int CountItems(IStorable item) {
        return count;
    }
}

商店< T> 将保持通用的,但你会被转换为网​​上商店可以访问它的 CountItems

Your Store<T> would remain generic, but you would get access to its CountItems by casting to IStore:

var x = (IStore)Activator.CreateInstance(constructedType, new object[] { someParameter });
var count = x.CountItems((IStorable)someObjectThatImplementsStorable);

这篇关于如何使用激活创建一个通用类型的实例和铸造回的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆