如何为Activator.CreateInstance类型没有构造函数?

时间:2019-01-02 12:46:54

标签: c#

例如:

class TestType
{
   public int a;
   public int b;
}

TestType obj = Activator.CreateInstance(typeof(TestType), 1, 2) as TestType;

然后obj.a==1obj.b==2吗?有人知道如何解决我的问题吗?

3 个答案:

答案 0 :(得分:7)

不可能,请尝试

TestType obj = Activator.CreateInstance(typeof(TestType)) as TestType;
obj.a = 1;
obj.b = 2;

答案 1 :(得分:2)

TestType obj = Activator.CreateInstance(typeof(TestType), 1, 2) as TestType;

这是重载Activator.CreateInstance(type,params object [] args);其中args是构造函数的输入。因此,您可以使用Antoines解决方案,也可以将测试类型类更改为:

TestType obj = Activator.CreateInstance(typeof(TestType), 1, 2) as TestType;

class TestType
{
    public TestType(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public int a;
    public int b;
}

答案 2 :(得分:0)

您正在使事情变得混乱。语法new TestType { a=1, b=2 } not 调用的构造函数。这是调用隐式或默认构造函数并一次性设置一些属性的快捷方式。但是所有类都有构造函数。至少是隐式的。

我不知道您的最终目标是什么,但是如果您使用Activator创建实例,那么在编译时可能没有类型。因此,您无法通过类型本身访问属性,您需要调用PropertyInfo.SetValuehttps://docs.microsoft.com/en-us/dotnet/api/system.reflection.propertyinfo.setvalue?view=netframework-4.7.2

请参见以下示例:

class TestType
{
    public int a;
    public int b;
}

void Main()
{
    var typeName = typeof(TestType).FullName; // we have a string from here on

    var type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(x => x.FullName == typeName); // get the type based on the name

    var obj = Activator.CreateInstance(type); // object of this type, but without compile time type info

    var member = type.GetField("a"); // we know, that this is a field, not a property   
    member.SetValue(obj, 1); // we set value to 1
    member = type.GetField("b");
    member.SetValue(obj, 2); // we set value to 2

    Console.Write($"See values: a={((TestType)obj).a}, b={((TestType)obj).b}");
}

在最后的代码行中,我重新引入了编译时类型,只是为了表明构造的对象已按我们期望的方式设置了成员。

通常,您很可能会寻找扩展某些基本类型或实现接口的类型,但是在某些情况下,例如,您从配置中获得了完全合格的类型名称。