mercredi 11 avril 2018

Can I create an instance by reflection and specify the overloaded "params" constructor when there is only one argument c#?

I have a type that has two constructors (ConstructorTestClass), one that has a single parameter of params TestClass[] and the other of TestClass. I have to invoke an instance of TestClass by reflection and then invoke an instance of ConstructorTestClass by reflection using the TestClass instance as the constructor argument.

I want to be able to create my instance of ConstructorTestClass using the params constructor.

Here is a code sample demonstrating my problem;

using System;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var assembly = typeof(ConstructorTestClass).Assembly;

            var parameter = assembly.CreateInstance(typeof(TestClass).FullName);

            var parameters = new object[] { parameter }; 

            var result = assembly.CreateInstance(typeof(ConstructorTestClass).FullName, false, BindingFlags.CreateInstance, null, parameters, null, null);

            Console.WriteLine(result);
            Console.ReadLine();
        }
    }

    internal class ConstructorTestClass
    {
        private readonly string _constructor;
        public string ConstructorSignature { get; }
        public ConstructorTestClass(params TestClass[] foo)
        {
            _constructor = "params TestClass[] foo";
        }

    public ConstructorTestClass(TestClass foo)
    {
        _constructor = "TestClass foo";
    }

    public override string ToString() => _constructor;
    }

    internal class TestClass { }
}

The second constructor (TestClass Foo) is always invoked. If I comment out this constructor the code continues to work but instead calls the other constructor.

I can also get the params constructor to be invoked if I cast the parameters to the correct type;

var parameters =  new object[] { new TestClass[] { parameter as TestClass } };

This does not solve the problem however because I would not know the type in the real code in which I need this feature.

I have also tried getting the specific constructor I need and invoking it directly;

var constructor = typeof(DummyConstructorTestClass).GetConstructor(new Type[] { typeof(TestClass[]) });
var result = constructor.Invoke(new object[] { new object[] { parameter } });

Unfortunately this also fails because of the type mismatch (object[] is not TestClass[])

Can I invoke the params constructor by reflection in this case?





Aucun commentaire:

Enregistrer un commentaire