【问题标题】:Activator.CreateInstance for create Ironpython classActivator.CreateInstance 用于创建 Ironpython 类
【发布时间】:2015-03-24 15:56:04
【问题描述】:

是否可以使用Activator.CreateInstance 根据 Ironpython 中声明的类型在 c# 中创建一个类?如果我尝试使用它,我总是会收到消息,即找不到无参数构造函数。

谢谢!

【问题讨论】:

  • @Veverke 我不明白你的意思。
  • 只有一个无参数构造函数,这就是我很困惑的原因。

标签: c# .net instance ironpython activator


【解决方案1】:

Activator.CreateInstance 有很多重载。您应该使用需要类型和属性的附加对象数组的重载

你可以创建这个类的一个实例

public class MyClass
{
    public MyClass(int _int, string _string, bool _bool)
    {
    }
}

Activator.CreateInstance(typeof(MyClass), new object[] { 1, "string", true });

正如die maus 所说,与其他解决方案相比,Activator.CreateInstance 可能会很慢。但这完全取决于你想做什么。如果您想构建依赖注入框架,我建议您使用替代方法。如果你想在运行时创建一个类型,不管它需要 3 毫秒还是 15 毫秒都没有关系。

我写了一个快速基准测试:

        var sw = new System.Diagnostics.Stopwatch();
        sw.Start();
        for (int i = 0; i < 100000; i++)
        {
            var file = new System.IO.FileInfo(@"c:\temp\file");
        }
        var t1 = sw.ElapsedMilliseconds;

        var args = new object [] { @"c:\temp\file" };
        sw.Restart();
        for (int i = 0; i < 100000; i++)
        {
            var file = Activator.CreateInstance(typeof(System.IO.FileInfo), args);
        }
        var t2 = sw.ElapsedMilliseconds;
        Console.WriteLine("t1: {0}", t1);
        Console.WriteLine("t2: {0}", t2);

输出:

t1: 466
t2: 1246

在大多数情况下我不会考虑这个huge...

【讨论】:

  • 您实际上可以省略new object[] { 1, "string", true },只需将参数指定为...,因为args-argument 是params-参数。 Activator.CreateInstance(typeof(MyClass), 1, "string", true);
  • 谢谢,但是: 1. 我没有参数。 2. 性能不达标。 3.我使用dlr类,这似乎是问题
  • @BendEg - 错误消息no parameter-less constructor is found 非常清楚。也许您可以发布一些示例代码或查看type.GetConstructors() 以了解您的班级有什么.ctors
【解决方案2】:

简短的回答,不,不可能。

【讨论】:

    【解决方案3】:

    假设您使用 Activator.CreateInstance 的重载仅采用 Type 参数,您的类必须有一个采用 零参数的构造函数。

    如果你坚持使用Activator.CreateInstance 的重载,它只接受Type 参数,而不是overload that takes a collection of objects as args,那么你必须实现一个无参数构造函数。

    例子:

    public class MyClass
    {
        public MyClass() // <-- parameterless constructor
        {
        }
    }
    

    如果该类不是您的代码的一部分,或者在您无法控制源代码的库中。如果基类不是sealed,那么您也许可以继承该类,然后在派生类中添加parameterless constructor

    例子:

    public class MyClass : SomeBaseClassYouDontControl
    {
        public MyClass() : base(null) // <-- still a parameterless constructor
        {
        }
    }
    

    但是,我会反对使用Activator.CreateInstance,因为它的性能很差,现在它比以前的 C# / .NET 版本要好一些。 @SchlaWiener 的回答包含更多关于此的信息。

    这个问题也可能与您的问题有关。 Activator.CreateInstance Performance Alternative

    【讨论】:

    • 没有什么可说的“[...] 你的类必须有一个接受零参数的构造函数。” - override which takes constructor arguments 呢?
    • 我假设 OP 正在使用仅采用 Type-argument 的 Activator.CreateInstance 的重载。但我会在我的帖子中添加信息。
    猜你喜欢
    • 2016-01-17
    • 2015-10-14
    • 1970-01-01
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 2012-05-15
    • 2015-08-12
    • 1970-01-01
    相关资源
    最近更新 更多