问题描述
在下面的代码中,是否可以将x转换为要传递给 Activator.CreateInstance
的类型,而无需提前知道它是什么?我尝试传递 typeof ...
,但这不起作用.
In the code below, is it possible to convert x to the type you're passing into Activator.CreateInstance
without knowing what it is ahead of time? I tried passing in typeof...
but that doesn't work.
var testClasses = AppDomain.CurrentDomain.GetAssemblies()
.Single(a=>a.FullName.StartsWith("VerifyStuff")).GetTypes()
.Where(t=>t.UnderlyingSystemType.Name.StartsWith("VerifyXXX"));
var x = Activator.CreateInstance(testClasses.ElementAt(0));
谢谢!
推荐答案
您只需要强制转换:
MyObject x = (MyObject) Activator.CreateInstance(testClasses.ElementAt(0));
当然,如果您在 testClasses
中具有各种类型的类型,这将变得更加困难.如果它们都衍生自相同的基类或实现相同的接口,则可以强制转换为该基类或接口.
of course this is going to be more difficult if you have a whole range of types in testClasses
. If they are all derived from the same base class or implement the same interface then you can cast to that base class or interface.
更多一点解释:x 是 是您传递给 CreateInstance
的类型,但它被强制转换为对象,因为CreateInstance不知道可能要扔给它什么.创建具体实例后会发生问题-无法将其传递给另一个(强类型化)函数,因为您将其作为 object
.有两种解决方法:
just to be a little more explanatory: x is of the type you passed in to CreateInstance
, but it is cast as an object, because CreateInstance has no idea what you may throw at it. You problem occurs after you've created your concrete instance - you can't pass it into another (strongly typed) function because you have it as an object
. There are a couple of ways around this:
- 如上所述,
-
让它们全部派生自相同的基类或接口,以便您可以将它们作为该基类或接口类型进行传递
as i mentioned above, have them all derive from the same base class or interface, so that you can pass them around as that base class or interface type
如果您有一个需要在这些具体实例上执行操作的函数,请创建一个通用函数来执行此操作:
if you have a function that needs to perform an operation on those concrete instances, create a generic function to do it:
public T MyFunc(T myConcreteInstance)
{
... do whatever it is i need to do...
}
这很丑陋,但是可能很难避免...使用大的 if..else if 语句来确定它们的类型,然后再对其进行操作(提示:避免这种情况使用上面的选项#1 ...):
this is ugly, but it may be difficult to avoid... use a big if..else if statement to determine their types before operating on them (hint: to avoid this use option #1 above...):
Type t = myConcreteInstance.GetType();
if (t == typeof(someType1))
{
}
else if (t == typeof(someType2))
{
}
... etc ...
如果此时您在考虑为什么我不只是创建通用版本的CreateInstance()?" 然后不要打扰-已经有一个,但仍然没有解决在传递内容之前先进行强类型输入的问题.引用MSDN:
If at this point you are thinking "why don't i just make a generic version of CreateInstance()?" then don't bother - there already is one, it still doesn't solve your issue of having things strongly typed before passing them around. To quote MSDN:
如果要使用CreateInstance,这是因为您不提前知道类型,因此您必须解决该问题.
If you are going to use CreateInstance, it's because you don't know the type ahead of time, therefore you must work around it.
这篇关于如何将Activator.CreateInstance返回的对象转换为它转换的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!