简体   繁体   English

尝试使用 Activator.CreateInstance(MyType)

[英]Trying to use Activator.CreateInstance(MyType)

I have the following problem:我有以下问题:

public class MyType
{
    public void method(int a, params object[] p){} 
    public void MyType()
    {
        method(5);
    }
}

When I use a constructor everything is fine but when I try to use Activator.CreateInstance(MyType);当我使用构造函数时,一切都很好,但是当我尝试使用Activator.CreateInstance(MyType);

void Factory()
{
    string componentPath = "MyType.dll";
    Assembly component = Assembly.LoadFrom(componentPath);
    Type myType= component.GetType("MyType");
    Activator.CreateInstance(myType);
}

it fails with exception MyType.method(int32) is not found.它失败并出现异常MyType.method(int32) is not found。 Important to notice that before I added params object[] p to method everything worked fine.重要的是要注意,在我将params object[] p添加到方法之前,一切正常。

Thank You.谢谢你。

If you use methods with optional parameters or methods with params to pass a variable number of parameters, what you're doing is telling the compiler that when you CALL that method, will it please insert the necessary parameters for you?如果您使用带有可选参数的方法或带有params的方法来传递可变数量的参数,那么您所做的是告诉编译器当您调用该方法时,它会为您插入必要的参数吗? Optional parameters and params arrays are inserted in the calling code, not the called code.可选参数和参数 arrays 插入调用代码,而不是被调用代码。 (See one of Eric Lipperts blog posts on optional parameters for some elaboration). (有关可选参数的详细说明,请参阅 Eric Lipperts 的一篇博客文章)。

You're not using the C# compiler, and the Reflection API does not insert those parameters for you.您没有使用 C# 编译器,反射 API 不会为您插入这些参数。 For example, you can test this not just by reflection, but also by using two assemblies: Assembly A declares method(int X) ;例如,您不仅可以通过反射进行测试,还可以使用两个程序集进行测试: 程序集 A 声明method(int X) it is compiled and the dll is referenced by assembly B. This assembly B contains a call to method(42) .它被编译并且 dll 被程序集 B 引用。这个程序集 B 包含对method(42)的调用。 This works fine, Now, if you recompile assembly A and change the signature to method(int X, object bla=null) or method(int X, params object[] blas) , then assembly B stops working - it contains an invalid call.这工作正常,现在,如果您重新编译程序集 A 并将签名更改method(int X, object bla=null)method(int X, params object[] blas) ,那么程序集 B 停止工作 - 它包含无效调用. Even so, the source code to assembly B is still OK - you just need to recompile.即便如此,程序集 B 的源代码仍然可以 - 您只需要重新编译即可。

Reflection simply happens not to do any of the optional parameter magic for you.反射只是碰巧没有为您做任何可选参数魔术。 It could , certainly - but it doesn't.可以,当然 - 但它没有。 While reflection doesn't support this, the DLR does, which brings me to the following...虽然反射不支持这一点,但 DLR 支持,这让我想到了以下内容......

Workaround: Try using the C# keyword dynamic , if possible (which for constructors, it isn't AFAIK) - that attempts to emulate C# calling conventions more closely and supports stuff like optional and named parameters.解决方法:尝试使用 C# 关键字dynamic ,如果可能的话(对于构造函数,它不是 AFAIK) - 尝试更紧密地模拟 C# 调用约定并支持诸如可选和命名参数之类的东西。 You may need to change the way your API is set up, however to use methods rather than constructors.您可能需要更改 API 的设置方式,但要使用方法而不是构造函数。 It's hard to give more precise advice without seeing actual code.如果没有看到实际代码,很难给出更准确的建议。

Alternatively: You may be trying to load plugins, by the looks of it.或者:从外观上看,您可能正在尝试加载插件。 .NET has some premade infrastructure to help you with this: Add-ins and Extensibility , which may make your task easier. .NET 有一些预制的基础设施可以帮助您解决这个问题:插件和可扩展性,这可能会使您的任务更轻松。

(Note: your example code is incomplete - I'm making a slight guess that method is in reality a constructor, but you should really post the actual code or at least a snippet that actually fails). (注意:您的示例代码不完整 - 我略微猜测该method实际上是一个构造函数,但您应该真正发布实际代码或至少一个实际失败的片段)。

This won't work because you have to pass at least 2 parameters in your call to method().这是行不通的,因为您必须在对 method() 的调用中传递至少 2 个参数。 The params modifier doesn't mean "optional". params修饰符并不意味着“可选”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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