Activator.CreateInstance不适用于隐式强制转换方案 [英] Activator.CreateInstance not working for implicit cast scenario

查看:98
本文介绍了Activator.CreateInstance不适用于隐式强制转换方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use Activator.CreateInstance Method to dynamically create a new instance. But when I pass the instance of a class that is implicitly castable to the actual type (in constructor), I get the System.MissingMethodException. Here is my testing code that I'm using to verify :

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

当我通过时发生相同的事情在派生类实例中(也在上面的代码中)。因此,这是预期的行为还是我的代码做错了。解决这种情况的正确方法是什么?谢谢。

Same thing occurs when I pass in a derived class instance(which is also in the code above). So, is this the expected behavior or I'm doing something wrong in my code. What would be the proper way out for this situation. Thanks.

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

About the second part, my implementation is wrong(as mentioned in the answer below), and once the code was modified accordingly, the required instance is created using derived class as parameter successfully. BUT, about the implicit casting case, still a workaround is required. Maybe some patterns-related solution, or some tricky/hacky implementation, that would generate a new instance even for implicitly castable types?

推荐答案

对于第一种情况:

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

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

This call fails because the class Test has no constructor taking one argument of type NewClass. You defined an implicit cast operator, but this is not working with the reflection approach of the Activator class as it is searching for a constructor on Test which takes an argument of type NewClass and this fails. Even if the creation via the new operator works (as the cast will be evaluated prior to the new operation). For the reflection, the compiler/clr does not know it needs to perform the cast because it only looks at the types.

也许您打算用<$来调用ctor。 c $ c> NewClass2 :

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

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

The second call fails because you need to pass an instance of SubTest and not Test. The other way would be okay (if the ctor needs Test and you pass SubTest).

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

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

The MissingMethodException is right at this point because you are trying to call a constructor which isn't defined.

这篇关于Activator.CreateInstance不适用于隐式强制转换方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆