从类名创建精确的实例

时间:2015-05-15 08:07:53

标签: c#

我有两个课程:Class1Class2

class Class1
{
    public void method();
}

class Class2
{
    public void method();
}

在另一个地方我有类类型,我想从中创建一个实例。 类型为typeof(Class1)或typeof(Class2)

public void CreateInstance(Type type)
{
    var instance = Activator.GetInstance(type);
    instance.method(); //compile error: object doesn't contain method
}

解决方案是我定义一个接口,我的类实现该接口。

interface IInterface
{
    void method();
}

public void CreateInstance(Type type)
{
    var instance = Activator.GetInstance(type);
    ((IInterface)instance).method();
}

因为我无法访问课程定义,所以我无法做到这一点。我怎么能这样做?

3 个答案:

答案 0 :(得分:4)

这就是你需要的:

public void CreateInstance(Type type)
{
    var instance = Activator.CreateInstance(type);
    type.GetMethod("method").Invoke(instance, null);
}

或者,使用dynamic

public void CreateInstance(Type type)
{
    dynamic instance = Activator.CreateInstance(type);
    instance.method();
}

注意:您的代码中有GetInstance而不是CreateInstance,但我更正了。

答案 1 :(得分:1)

通过使用通用方法和dynamic

,您可以完全避免反射和性能问题
public void CreateInstance<T>() where T:new()
{
    dynamic instance=new T();
    instance.method();
}

只需传递类型即可调用:

CreateInstance<Class1>();
CreateInstance<Class2>();

使用反射或使用dynamic时,类型安全性会丢失。检查是否存在具有反射的方法并不比运行时抛出异常更安全或风险更小 - 在这两种情况下都必须处理异常情况。发生此异常时,您将要做什么

使用dynamic时,缺少的方法会引发RuntimeBinderException,指出方法丢失。如果我将方法调用从method更改为method1,我会得到一个例外说明:

  

&#39; ConsoleApplication24.Class1&#39;不包含&#39; method1&#39;

的定义

这样代码支付正常情况下的反射惩罚。这也更安全 - 没有办法可以错过异常。

提供编译类型安全性的唯一方法是让类实现一个接口并将其用作通用约束,例如:

public static void CreateInstance<T>() where T : ISomething, new()
{
    var instance = new T();
    instance.method();
}

答案 2 :(得分:0)

最好的选择是使用界面来保证安全。但是如果你不能这样做,你可以通过反思来调用这个方法:

<div ng-repeat="(key,value) in options" ng-click="Add()">{{value}}</div>

然后你打电话给:

 $scope.options = {
    one: 1,
    two: 2,
    three: 3
}

如果方法不为空,请记住添加一些检查