【问题标题】:Trying to use Activator.CreateInstance(MyType)尝试使用 Activator.CreateInstance(MyType)
【发布时间】:2011-09-01 13:14:14
【问题描述】:

我有以下问题:

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

当我使用构造函数时一切都很好,但是当我尝试使用 Activator.CreateInstance(MyType);

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

它失败,异常 MyType.method(int32) is not found。 重要的是要注意,在我将 params object[] p 添加到方法之前,一切正常。

谢谢。

【问题讨论】:

  • 缺少代码?也请重新格式化您的帖子。
  • 我认为如果您将参数传递给该方法,您可以避免您的问题。只需将您的方法称为 method(5, new object[0]);
  • 你的代码不会为初学者编译

标签: c# reflection activation


【解决方案1】:

如果您使用带有可选参数的方法或带有params 的方法来传递可变数量的参数,您所做的是告诉编译器当您CALL该方法时,它会请为您插入必要的参数? 可选参数和 params 数组被插入到调用代码中,而不是被调用代码中。(有关详细说明,请参见 one of Eric Lipperts blog posts on optional parameters)。

您没有使用 C# 编译器,反射 API 不会为您插入这些参数。例如,您不仅可以通过反射进行测试,还可以使用两个程序集进行测试:程序集 A 声明 method(int X);它被编译并且dll被程序集B引用。这个程序集B包含对method(42)的调用。这很好用!现在,如果您重新编译程序集 A 并将签名更改method(int X, object bla=null)method(int X, params object[] blas),则程序集 B 将停止工作 - 它包含无效调用。即便如此,程序集 B 的源代码仍然可以 - 您只需要重新编译即可。

反射只是碰巧没有为你做任何可选参数的魔法。它可以,当然 - 但它没有。虽然反射不支持这一点,但 DLR 支持,这让我想到了以下内容......

解决方法:如果可能,请尝试使用 C# 关键字 dynamic(对于构造函数,它不是 AFAIK)- 尝试更接近地模拟 C# 调用约定并支持可选和命名参数。您可能需要更改 API 的设置方式,但要使用方法而不是构造函数。不看实际代码很难给出更准确的建议。

或者:从外观上看,您可能正在尝试加载插件。 .NET 有一些预制的基础设施可以帮助您:Add-ins and Extensibility,这可能会使您的任务更轻松。

(注意:您的示例代码不完整 - 我略微猜测 method 实际上是一个构造函数,但您应该真正发布实际代码或至少一个实际失败的 sn-p )。

【讨论】:

  • 非常感谢您的回答很棒!很抱歉我无法正确定义我的问题。
  • 我知道你已经接受了这个作为答案,所以你可能已经解决了你的问题,但你还能修复代码示例吗?这将使您的问题对其他人有用,我敢打赌 Heandel 会删除反对票...
【解决方案2】:

这不起作用,因为您必须在调用 method() 时至少传递 2 个参数。 params 修饰符并不意味着“可选”。

【讨论】:

  • 甚至可选参数在调用现场也不是可选的:blogs.msdn.com/b/ericlippert/archive/2011/05/16/…
  • @Heandel:如果您是从 C# 代码调用 - 当然可以。但他正在使用反射;这是一种需要对象数组作为第二个参数的方法。 intent 是允许简单的语法糖,其中数组内容看起来像参数,但 实现 只是一个数组。它不是可选的,也不是“自动”传递的——编译器会为你插入参数。
  • @Eamon Nerbonne:我认为你必须发表你的评论作为答案。
  • @Eamon Nerbonne:编译器在编译 MyType 类时不应该添加缺少的参数吗?
  • 它在编译你的调用到方法时添加缺少的参数,而不是在编译方法本身时。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多