Activator.CreateInstance不适用于隐式强制转换方案

时间:2014-01-05 09:55:03

标签: .net oop reflection activator

我正在尝试使用 Activator.CreateInstance 方法动态创建新实例。但是当我传递一个隐式可转换为实际类型的类的实例(在构造函数中)时,我得到 System.MissingMethodException 。 这是我用来验证的测试代码:

    using System;

    namespace ActivatorTest1
    {
        class Program
        {
            static void Main(string[] args)
            {
                Test t = new Test(new string[] { "abc" });
                NewClass nc = new NewClass(new SubTest("apple"));
                NewClass2 nc2 = nc;
                try
                {
                    Object[] paramList = new object[] { nc }; // nc is an instance of NewClass, which is implicitly castable to NewClass2
                    Activator.CreateInstance(typeof(Test), paramList);
                    Console.WriteLine("Instance successfully created");
                    Console.WriteLine("**************************");
                }
                catch (Exception exc)
                {
                    Console.WriteLine("INSTANCE CREATION FAILED FOR IMPLICIT CASTING SCENARIO. \r\n\r\n " + exc);
                }

                Console.WriteLine("\r\n\r\n\r\n****************************************************\r\n\r\n\r\n");
                try
                {
                    Object[] paramList = new object[] { t }; // Although t is an instance of Test which is the base class for SubTest, MissingConstructorException is thrown
                    Activator.CreateInstance(typeof(NewClass), paramList);
                    Console.WriteLine("Instance successfully created");
                    Console.WriteLine("**************************");
                }
                catch (Exception exc)
                {
                    Console.WriteLine("INSTANCE CREATION FAILED FOR DERIVED CLASS SCENARIO. \r\n " + exc);
                }
                Console.ReadKey();
            }
        }

        class Test
        {
            public Test(string[] strArr)
            { }

            public Test(NewClass2 nc2)
            { }
        }

        class SubTest : Test
        {
            public SubTest(string str)
                : base(new string[] { str })
            { }
        }

        class NewClass // implicitly castable to NewClass2
        {
            public NewClass(SubTest st)
            { }
        }

        class NewClass2
        {
            public NewClass2()
            { }

            public static implicit operator NewClass2(NewClass nc)
            {
                return new NewClass2();
            }
        }
    }

当我传入派生类实例(也在上面的代码中)时,会发生同样的事情。那么,这是预期的行为还是我在代码中做错了什么。对于这种情况,什么是正确的出路。感谢。

编辑:关于第二部分,我的实现是错误的(如下面的答案中所述),并且一旦相应地修改了代码,就会使用派生类作为参数成功创建所需的实例。 但是,关于隐式转换案例,仍然需要解决方法。也许某些与模式相关的解决方案,或者一些棘手/ hacky实现,即使对于隐式可转换类型也会生成新实例?

1 个答案:

答案 0 :(得分:1)

对于第一种情况:

Activator.CreateInstance(typeof(Test), new object[] { new NewClass(...) });

此调用失败,因为类Test没有构造函数接受类型NewClass的一个参数。 编辑:您定义了一个隐式强制转换运算符,但这不适用于Activator类的反射方法,因为它正在Test上搜索构造函数,它接受一个参数NewClass类型,但失败了。即使通过new运算符进行创建也是有效的(因为演员将在new运算之前进行评估)。对于反射,编译器/ clr不知道它需要执行转换,因为它只查看类型。

也许你打算用NewClass2打电话给ctor:

Activator.CreateInstance(typeof(Test), new object[] { new NewClass2(...) });

第二次调用失败,因为您需要传递SubTest而不是Test的实例。另一种方式是可以的(如果ctor需要Test并且您通过了SubTest)。

Activator.CreateInstance(typeof(NewClass), new object[] { new SubTest(...) });

此时MissingMethodException正确,因为您正在尝试调用未定义的构造函数。