使用Activator创建实例

时间:2012-10-13 17:33:03

标签: c# reflection activator

假设我们有一些课程

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

我有一个Type变量

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

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

object instance = Activator.CreateInstance(t);

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

4 个答案:

答案 0 :(得分:5)

如果你想避免反思,那么

public interface IClass { }
class Class1 : IClass { }
class Class2 : IClass { }
class Class3 : IClass { }

IClass instance = (IClass)Activator.CreateInstance(t);

答案 1 :(得分:3)

除非有一些共同的基类或接口全部共享,否则 - 你可以称之为“对象”。考虑让他们都实现一个接口,然后转换为。

答案 2 :(得分:2)

您可以使用dynamic关键字:

dynamic instance = Activator.CreateInstance(t);

这就像你使用object一样,但在这种情况下,类型只在运行时才知道,所以在你没有运行程序之前,它支持所有内容。 处理 Reflection 时非常常见。

了解更多信息look here

答案 3 :(得分:1)

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)。