【问题标题】:Is it possible to add a method to an EXISTING class at runtime? why or why not?是否可以在运行时向 EXISTING 类添加方法?为什么或者为什么不?
【发布时间】:2012-06-22 18:28:57
【问题描述】:

我想这可能会使用 Reflection.Emit,

a similar question on SO 只回答如何动态创建类/方法,而不是如何更新现有类。

类似地,是否可以在运行时删除方法/类?如果是这样,我想可以删除该类,然后用旧方法和新方法将其添加回来。

提前致谢。

附:我对此没有预期用途,只是出于好奇。

【问题讨论】:

  • 这是一个完美的例子,说明为什么 SO 问题应该在每个帖子中只包含一个问题。 Marc 和 Henk 分别回答了您提出的一个单独的问题,并且都是很好、正确的答案。您选择哪一个作为正确并接受?请限制自己在每个帖子中回答 一个 问题,以避免出现这种情况,即其中一个响应者获得奖励,而另一个则没有,即使两个答案都很好、正确并回答了您的问题。
  • 好的。将来我会努力记住这一点。问题而不是方法/对象的单一目的原则。既然契约已经完成,我可能不应该改变它。

标签: c# dynamic reflection.emit


【解决方案1】:

在常规 C#/.NET 中,答案是简单的“否”。你能做的最多就是写一个DynamicMethod,它可以表现类似于那种类型的方法(访问私有字段等),但它永远不会出现在 API 上——你只是结束了与代表。

如果你使用dynamic,你几乎可以做任何你想做的事情。您可以使用ExpandoObject 来模拟它,方法是附加委托 来代替方法,但是在自定义动态类型上,您几乎可以做任何事情——但这只会影响使用dynamic API 的调用者。对于基本的ExpandoObject 示例:

dynamic obj = new ExpandoObject();
Func<int, int> func = x => 2*x;
obj.Foo = func;
int i = obj.Foo(123); // now you see it
obj.Foo = null; // now you don't

对于属性和事件(不是方法),您可以使用System.ComponentModel 方法来更改运行时显示的内容,但这只会影响通过System.ComponentModel 获得访问权限的调用者,这主要意味着: UI 数据绑定。这就是DataTable 将列表示为伪属性的方式(暂时忘记“类型化数据集”——没有这些也可以工作)。

为了完整起见,我还应该提到扩展方法。这些更多的是编译器技巧,而不是运行时技巧 - 但有点允许您将方法添加到现有类型 - 对于“add”的小值。

ORM 等常用的最后一个技巧是动态子类化类型,并在子类中提供附加功能。例如,覆盖属性以拦截它们(延迟加载等)。

【讨论】:

  • 哈哈,“对于 add 的小值”。我想这对静态方法意味着:-P.
  • @user420667 不,实际上我的意思是“它们不是类型上的真正方法”。
  • 反应很好。关于为什么的任何想法?它会破坏某种开发原则/难以实施吗?
【解决方案2】:

是否可以在运行时删除方法/类?

假设这是可能的。对这些方法的调用将失败并产生未定义的(但通常是灾难性的)行为。

所以我确定这是不可能的。

【讨论】:

  • 未定义通常意味着灾难性的! ;)
  • catch(UndefinedMethod/UndefinedClassException) ? :-P
  • @user420667 有MissingMethodExceptionTypeLoadException。当您针对程序集的一个版本构建代码,然后针对缺少方法或类型的另一个版本运行代码时,可能会发生这种情况。
  • 仅仅因为它可能导致运行时错误并不意味着这就是不能这样做的原因。
  • 使用动态你进入DLR的领域,所以MissingMethodException将在运行时抛出,而不是编译时。
猜你喜欢
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 1970-01-01
  • 2015-03-23
  • 2017-06-26
  • 1970-01-01
相关资源
最近更新 更多