简体   繁体   中英

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? 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. 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. 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.

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...

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

Assuming you use the overload of Activator.CreateInstance only takes the Type argument your class must have a constructor that takes zero arguments.

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.

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.

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. @SchlaWiener's answer contains much more information about this.

This question, might also be relevant to your question. Activator.CreateInstance Performance Alternative

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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