【问题标题】:How to convert object returned by Activator.CreateInstance to the type it converted?如何将 Activator.CreateInstance 返回的对象转换为它转换的类型?
【发布时间】:2011-08-10 16:50:59
【问题描述】:

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

谢谢!

【问题讨论】:

    标签: object types instance


    【解决方案1】:

    你只需要投射它:

    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,那是因为你事先不知道类型,所以你必须解决它。

    【讨论】:

    • 感谢您的回复。我知道您可以将对象装箱并获取类型,就像我只是在想可能有一些通用的方法可以传入对象并取回实际的类型对象。猜不到。
    • @BrokenGlass - 我已经扩展了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    相关资源
    最近更新 更多