在我的反射式 C# 代码中,我迭代接口上的方法并发出一个类,a) 被声明为实现接口 b) 实现了
GetMethods()
返回的所有方法。
var methods = typeof(T).GetMethods(); // T is interface
foreach (var methodInfo in methods)
{
var parameters = methodInfo.GetParameters().Select(p => p.ParameterType).ToArray();
var method = typeBuilder.DefineMethod(
methodInfo.Name,
MethodAttributes.Public | MethodAttributes.Virtual,
methodInfo.ReturnType,
parameters);
... // Emit IL
这不仅创建了方法,还创建了作为方法对的属性和事件(get_set_/add_remove_)。
动态创建的类被 CLR 接受为接口的实现,并且调用对象上的属性和事件(转换为接口)可以正常工作。然而,在类型生成器中,有
DefineProperty
以及 DefineMethod
。使用 ildasm,如果仅使用 DefineMethod
,我可以确认声明中缺少“.property”。将接口的属性和事件当作“只是”方法来实现是不是很顽皮?或者这完全合法吗?
像这样实现接口的属性和事件是不是很顽皮? 它们只是“方法”?
是的,确实如此。您将无法将属性用作属性(使用
dynamic
时)。
这很顽皮,你不想这样做。
如果这样做,从调用它们的其他代码的角度来看,您的对象可能很好,但从反射的角度来看它们将不完整。因此,您的对象在任何需要正确反射信息的情况下都不会正确运行。
正如另一个答案所述,
Dynamic
就是这种情况的一个例子。
我根本不关心
Dynamic
。 Dynamic
是:
不良设计的解决方法,以及
它的使用会导致不可挽回的更糟糕的设计。
我明白
Dynamic
现在几乎是每个人的宠儿。那是因为现在几乎每个人都是脚本小子。
但是这里有一个更糟糕的问题:
如果您尝试在 Visual Studio 调试器的“Locals”或“Autos”窗口中查看对象,您生成的属性将不会出现! Visual Studio 调试器枚举对象的属性,以便决定在其中显示什么内容,因此,如果您的对象没有正确定义其属性,它们将不会显示。
我刚刚用自己的东西遇到了这个问题,并写了一个问答: