简体   繁体   English

用于创建Ironpython类的Activator.CreateInstance

[英]Activator.CreateInstance for create Ironpython class

Is it possible to use Activator.CreateInstance to create a class in c# based on a Type declared in Ironpython? 是否可以使用Activator.CreateInstance根据Ironpython中声明的Type在c#中创建一个类? If I try to use it, I always get the message, that no parameter-less constructor is found. 如果我尝试使用它,我总是会收到消息,找不到没有参数的构造函数。

Thank you! 谢谢!

Activator.CreateInstance has many overloads. Activator.CreateInstance有很多重载。 You should use the overload which requires a Type and an adition object array for the attributes 您应该使用需要类型和属性对象数组的重载

You can create an instance of this class 您可以创建此类的实例

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

with

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

As die maus said, Activator.CreateInstance may be slow compared to other solutions. 正如die maus所说,与其他解决方案相比,Activator.CreateInstance可能会比较慢。 But it totally depends what you want to do. 但这完全取决于您要做什么。 If you want to build an Dependency Injection Framework I would suggest you use an alternatives approach. 如果您想构建一个依赖注入框架,我建议您使用替代方法。 If you want to create a type at runtime and it does not matter if it takes 3 or 15 milliseconds you should be fine. 如果要在运行时创建类型,并且花费3或15毫秒无关紧要,那么就可以了。

I wrote a quick benchmark: 我写了一个快速基准测试:

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

Output: 输出:

t1: 466
t2: 1246

I would not consider this huge in most scenarios... 我不会考虑这个huge在大多数情况下...

简短的答案,不,这是不可能的。

Assuming you use the overload of Activator.CreateInstance only takes the Type argument your class must have a constructor that takes zero arguments. 假设您使用Activator.CreateInstance的重载仅接受Type参数,则您的类的构造函数必须接受零参数。

If you insist on using the overload of Activator.CreateInstance which only takes the Type argument, and not for instance the overload that takes a collection of objects as args then you must implement a parameterless constructor. 如果您坚持使用仅带有 Type参数的Activator.CreateInstance的重载,而不是使用将对象集合作为args重载,则必须实现无参数构造函数。

Example: 例:

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

If the class is not part of your code, or in a library where you don't have control over the source code. 如果该类不是您的代码的一部分,或者不在您无法控制源代码的库中。 Then you might be able to inherit the class, provided the base class is not sealed and then add a parameterless constructor to your derived class. 然后,如果未sealed基类,则可以继承该类,然后将无parameterless constructor添加到派生类。

Example: 例:

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

However, i would advice against using Activator.CreateInstance because of its terrible performance, it is a bit better now than in previous versions of C# / .NET. 但是,我建议不要使用Activator.CreateInstance因为它的性能Activator.CreateInstance ,它现在比以前的C#/ .NET版本要好一些。 @SchlaWiener's answer contains much more information about this. @SchlaWiener的答案包含有关此的更多信息。

This question, might also be relevant to your question. 这个问题,也可能与您的问题有关。 Activator.CreateInstance Performance Alternative Activator.CreateInstance性能替代

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM