【问题标题】:Activator.CreateInstance not working for implicit cast scenarioActivator.CreateInstance 不适用于隐式转换场景
【发布时间】:2014-01-22 19:24:29
【问题描述】:

我正在尝试使用 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 的实现,即使对于隐式可转换类型也会生成一个新实例?

【问题讨论】:

    标签: .net oop reflection activator


    【解决方案1】:

    对于第一种情况:

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

    此调用失败,因为类Test 没有构造函数采用NewClass 类型的一个参数。 编辑: 您定义了一个隐式强制转换运算符,但这不适用于 Activator 类的反射方法,因为它正在搜索 Test 上的构造函数,该构造函数采用 @987654326 类型的参数@ 这失败了。即使通过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 在这一点上是正确的,因为您正在尝试调用未定义的构造函数。

    【讨论】:

    • 关于基派生类场景,是的,你是对的,在我相应地修改了ctor之后,实例创建成功。对于隐式转换场景,与您所说的不同, *Test t1 = new Test(new NewClass()); * 编译成功。但仅在通过 Reflection 创建实例时失败。如果这是 Activator.CreateInstance 所需的工作方式,那么为什么是我的下一个问题(关于内部工作的一些解释会有所帮助)。
    • NewClass2 和 NewClass 在任何意义上都不是继承的链接器,测试没有 NewClass 的 ctor,因此您发布的代码无法工作。一秒钟,我会解释为什么......
    • @MrClan 更新了我的答案-希望这可以为您解决问题。
    • 谢谢。任何想法,如何解决隐式转换的情况???也许与模式相关的解决方案,或者一些棘手/骇人听闻的实现,即使对于隐式可转换类型也会生成一个新实例???
    • @MrClan object[] paramList = new NewClass[] { ... } 怎么样?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 2013-07-03
    相关资源
    最近更新 更多