在.NET IL中是否可以将接口的属性和事件直接实现为方法?

问题描述 投票:0回答:2

在我的反射式 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”。将接口的属性和事件当作“只是”方法来实现是不是很顽皮?或者这完全合法吗?

c# .net clr cil
2个回答
4
投票

像这样实现接口的属性和事件是不是很顽皮? 它们只是“方法”?

是的,确实如此。您将无法将属性用作属性(使用

dynamic
时)。


0
投票

这很顽皮,你不想这样做。

如果这样做,从调用它们的其他代码的角度来看,您的对象可能很好,但从反射的角度来看它们将不完整。因此,您的对象在任何需要正确反射信息的情况下都不会正确运行。

正如另一个答案所述,

Dynamic
就是这种情况的一个例子。

我根本不关心

Dynamic
Dynamic
是:

  • 不良设计的解决方法,以及

  • 它的使用会导致不可挽回的更糟糕的设计。

我明白

Dynamic
现在几乎是每个人的宠儿。那是因为现在几乎每个人都是脚本小子。

但是这里有一个更糟糕的问题:

如果您尝试在 Visual Studio 调试器的“Locals”或“Autos”窗口中查看对象,您生成的属性将不会出现! Visual Studio 调试器枚举对象的属性,以便决定在其中显示什么内容,因此,如果您的对象没有正确定义其属性,它们将不会显示。

我刚刚用自己的东西遇到了这个问题,并写了一个问答:

发出的属性不会出现在调试器中

© www.soinside.com 2019 - 2024. All rights reserved.