【问题标题】:Create instance with Activator使用 Activator 创建实例
【发布时间】:2012-10-14 16:15:00
【问题描述】:

假设我们有一些类

class Class1{ }
class Class2{ }
class Class3{ }

我有一个类型变量

Type t = /*some type unknown at compile-time*/;

变量t 是Class1 或Class2 或Class3。我想创建该类的一个实例。据我所知,我可以使用以下语句:

object instance = Activator.CreateInstance(t);

但是我收到了一个对象。问题是:如何将此对象转换为变量t 中的类型。或者也许有人可以提出解决方法。 谢谢

【问题讨论】:

    标签: c# reflection activator


    【解决方案1】:

    如果你想避免反射,那么

    public interface IClass { }
    class Class1 : IClass { }
    class Class2 : IClass { }
    class Class3 : IClass { }
    
    IClass instance = (IClass)Activator.CreateInstance(t);
    

    【讨论】:

      【解决方案2】:

      除非有一些共同的基类或接口,所有 3 共享,你不能 - 你可以称之为“对象”。考虑让它们都实现一个接口,并转换为那个。

      【讨论】:

        【解决方案3】:

        您可以使用dynamic 关键字:

        dynamic instance = Activator.CreateInstance(t);
        

        这就像您使用object 一样,但在这种情况下,该类型仅在运行时才知道,因此在您不运行程序之前它支持所有内容。 在处理Reflection时很常见。

        欲了解更多信息look here

        【讨论】:

          【解决方案4】:

          has been told that you can't,但是,你可以。

          首先让我们看看你的代码:

          class Class1{ }
          class Class2{ }
          class Class3{ }
          
          void Main()
          {
              Type t = /*some type unknown at compile-time*/;
              object instance = Activator.CreateInstance(t);
          }
          

          还有你的问题:

          如何将此对象转换为变量 t 中的类型。

          好吧,如果我只看这些信息,那么答案是:你不能,因为变量t 中可能有无限的类型集,事实上,其中一些可能已经被定义在编写此代码之后(它们还不存在)。

          嗯 - 似乎是 - 还有一些其他信息:

          变量 t 是 Class1 或 Class2 或 Class3

          意味着您有一组有限的可能类型,它们可能位于变量 t 中。

          考虑到这一点,您可以检查它们,例如:

          class Class1{ }
          class Class2{ }
          class Class3{ }
          
          void Main()
          {
              var possibleTypes = new Type[]
              {
                  typeof(Class1),
                  typeof(Class2),
                  typeof(Class3)
              };
              Type t = possibleTypes[(new Random()).Next(possibleTypes.Length)];
              object instance = Activator.CreateInstance(t);
              if (t.Equals(typeof(Class1)))
              {
                  DoSomethingWithClass1(instance as Class1);
              }
              else if (t.Equals(typeof(Class2)))
              {
                  DoSomethingWithClass2(instance as Class2);
              }
              else if (t.Equals(typeof(Class3)))
              {
                  DoSomethingWithClass3(instance as Class3);
              }
          }
          
          void DoSomethingWithClass1(Class1 instance)
          {
              //...
          }
          
          void DoSomethingWithClass2(Class2 instance)
          {
              //...
          }
          
          void DoSomethingWithClass3(Class3 instance)
          {
              //...
          }
          

          它很好用,并且在每个类的方法中,您可以使用适合该类的任何东西。

          “它不是很通用”——你说——“我不想每次出现新类时都编写新方法!”。我同意,你可以在反射部门解决这个问题。但是,老实说,这是没有意义的。正如你已经被告知的那样,这些课程没有任何共同点,所以你最好 creating an interface to avoid Reflection

          另外,你想用那个对象做什么?您可能会找到所有类共有的方法,并在相关类将从现在开始实现的新接口中使用这些方法。

          好的,我知道在撰写本文时已经有一个公认的答案,但我还是想指出:是的,你可以。 (每次我发现有人说你不能做某事时,我都喜欢做双重检查:P)。

          【讨论】:

          • 感谢您的回答。事实上,我有很多分类(30-50),所以在这一点上编写 switch 案例对我来说不是一个好主意。通过创建通用基类找到解决方案。
          猜你喜欢
          • 1970-01-01
          • 2010-11-16
          • 2015-02-12
          • 2015-08-20
          • 1970-01-01
          • 2022-08-02
          • 2016-08-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多