如何将 Activator.CreateInstance 返回的对象转换为它转换的类型?
在下面的代码中,是否可以将 x 转换为您传递给 Activator.CreateInstance 的类型,而无需提前知道它是什么?我尝试传入 typeof...
但这不起作用。
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));
谢谢!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您只需要对其进行强制转换:
当然,如果您在
testClasses
中拥有一系列类型,这当然会更加困难。如果它们都派生自相同的基类或实现相同的接口,那么您可以转换为该基类或接口。编辑:
只是为了更具解释性: x is 是您传递给
CreateInstance
的类型,但它被转换为对象,因为 CreateInstance不知道你会扔什么给它。您的问题发生在您创建具体实例之后 - 您无法将其传递到另一个(强类型)函数,因为您将其作为对象
。有几种方法可以解决这个问题:正如我上面提到的,让它们全部派生自相同的基类或接口,以便您可以将它们作为基类或接口类型传递
如果您有一个需要对这些具体实例执行操作的函数,请创建一个泛型函数来做到这一点:
<前><代码>
公共 T MyFunc(T myConcreteInstance)
{
……做我需要做的一切……
}
这很丑陋,但可能很难避免...使用一个大的 if..else if 语句,用于在对它们进行操作之前确定它们的类型(提示:避免使用上面的选项 #1...):
<前><代码>
类型 t = myConcreteInstance.GetType();
if (t == typeof(someType1))
{
}
否则 if (t == typeof(someType2))
{
}
... ETC ...
如果此时您正在想“为什么我不只制作一个通用版本的 CreateInstance()?”那么就不用担心 - 那里已经是一个了,它仍然不能解决你在传递之前强类型化的问题他们周围。引用MSDN:
如果您打算使用 CreateInstance,那是因为您提前不知道类型,因此您必须解决它。
You simply need to cast it:
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.Edit:
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 anobject
. 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:
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...):
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:
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.
来自@slugster的回答:
对于阅读本文的人来说,可以采用替代策略:
并确定类型:
在我的情况下,我正在使用 Mediatr &我无法将 TResponse 转换为具体实现,而是求助于通用接口。在此示例中,我展示了一个 ICommonResult,所有 Generic CommonResult实现作为 TResponse 传入的。这是绕过长
if、elseif
或switch
类型检查的方法,例如:接口:
From @slugster's answer:
For people reading this an alternative strategy to this:
and working out the type:
In my situation I'm using Mediatr & I can't Cast the TResponse to a concrete implementation, instead I resort to a common Interface. In this example I show a ICommonResult that all Generic CommonResult<T's> implement that are passed in as the TResponse. This is how you can get around a long
if, elseif
orswitch
type check, eg:The Interface: