如何将Activator.CreateInstance返回的对象转换为它转换的类型?

时间:2011-04-22 00:10:20

标签: object types instance

在下面的代码中,是否可以将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));

谢谢!

1 个答案:

答案 0 :(得分:7)

你只需要施展它:

MyObject x = (MyObject) Activator.CreateInstance(testClasses.ElementAt(0));

当然,如果testClasses中有各种类型,这将会更加困难。如果它们都是从相同的基类派生或实现相同的接口,那么您可以转换为该基类或接口。

编辑:

  

是否可以将x转换为您传递给Activator.CreateInstance的类型,而不知道它是什么时候提前?

只是为了更具说明性:x 你传递给CreateInstance的类型,但是它被转换为对象,因为CreateInstance不知道你可能会抛出什么。您在创建具体实例后出现问题 - 您无法将其传递给另一个(强类型)函数,因为您将其作为object。有几种方法可以解决这个问题:

  • 如上所述,让它们都来自相同的基类或接口,以便您可以将它们作为基类或接口类型传递

  • 如果您有一个需要对这些具体实例执行操作的函数,请创建一个通用函数来执行此操作:

    
    public T MyFunc(T myConcreteInstance) 
    {
        ... do whatever it is i need to do...
    }
    
  • 这很难看,但可能很难避免......在操作它们之前使用一个大的 if..else if 语句来确定它们的类型(提示:避免这种情况)使用上面的选项#1 ...):

    
    Type t = myConcreteInstance.GetType();
    if (t == typeof(someType1))
    {
    
    }
    else if (t == typeof(someType2))
    {
    
    }
    ... etc ...
    

如果此时您正在考虑“为什么我不只是创建一个通用版本的CreateInstance()?”那么就不要打扰了 - 已经有一个,它仍然没有解决你在传递它们之前强力打字的问题。引用MSDN:

  

通常,应用程序代码中的CreateInstance没有用处,因为必须在编译时知道该类型。如果在编译时已知类型,则可以使用正常的实例化语法(C#中的new运算符,Visual Basic中的New,C ++中的gcnew)。

如果您打算使用CreateInstance,那是因为您提前不知道类型,因此您必须解决它。