如何使用 Activator 创建泛型类型的实例并将其转换回该类型?
我有一个通用类型 Store
并使用 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 });
我想做的是这样的:
var store = (Store<typeof(objectThatImplementsIStorable)>)x;
但由于明显的原因,这不起作用。作为替代方案,我尝试了:
var store = (Store<IStorable>)x;
在我看来,这可能有效,但给出了 InvalidCastException
。
如何再次访问我知道位于对象 x
中的 Store
方法?
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;
which could possibly work in my opinion, but gives an InvalidCastException
.
How do I get access again to the Store<T>
methods that I know are in the object x
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
由于实际类型
T
只能通过反射来使用,因此您还需要通过反射访问Store
的方法:EDIT 您还可以定义一个不使用泛型的附加
IStore
接口,并使用IStorable
代替:您的
Store
将保持通用,但你可以访问它的CountItems
通过转换为IStore
:Since the actual type
T
is available to you only through reflection, you would need to access methods ofStore<T>
through reflection as well:EDIT You could also define an additional
IStore
interface that does not use generics, and usesIStorable
instead:Your
Store<T>
would remain generic, but you would get access to itsCountItems
by casting toIStore
:就不能包起来吗?
类似的事情
或者我错过了你想做的事情吗?
IE
打印
Cant you just wrap it?
something like
or am i missing what you are trying to do?
IE
prints
我认为最合适的答案是“你不能这样做”。
您可以尝试引入一个接口
IStorage
并尝试使其协变或逆变(您见过这个选项吗?)。如果这不是一个选项,例如,如果您在Storage
中同时使用了输入和输出泛型类型,那么就无法实现您想要的功能。原因是由于这种情况,Storage
无法安全地用作Storage
:据我所知,您唯一可能的解决方法是将强制转换移出从这个方法并将对象强制转换到您知道所有确切类型的位置:
Most appropriate answer in my opinion would be 'you can't do it in this way'.
You might try introducing an interface
IStorage
and try making it covariant or contravariant (have you seen that option?). If it is not an option, for example if you have both input and output generic types used inStorage
, then there is no way to implement what you want. The reason is thatStorage<Beer>
cannot be safely used asStorage<IStorable>
due to this case:The only possible workaround for you as I see is to move casting out from this method and cast the object in the place where you know all the exact types:
T 必须是 Store类型避免使用 typeof(Store;
T must be the type Store<X> avoiding the use of typeof(Store<T>
假设 someObjectThatImplementsIStorable 的类型为 MyStorable。
例如
MyStorable someObjectThatImplementsIStorable = new MyStorable( );
... // 其余代码在这里。
那么 x 不能转换为 Store,但可以转换为 Store。以下内容将起作用: (Store)x
请注意,尽管 MyStorable 实现了 IStorable,但 Store 和 Store 之间没有关系。这是两个不同的类,互不派生。
u。
Let's say that someObjectThatImplementsIStorable is of type MyStorable.
e.g.
MyStorable someObjectThatImplementsIStorable = new MyStorable( );
... // rest of your code here.
Then x cannot be cast to Store, but it can be cast to Store. The following will work: (Store)x
Note that although MyStorable implements IStorable, there is no relationship between Store and Store. These are two distinct classes that do not derive from each other.
u.