C# 如何在运行时向方法添加属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/268426/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:50:50  来源:igfitidea点击:

How do I add attributes to a method at runtime?

c#reflectionattributesreflection.emit

提问by Simon

We're using Microsoft.Practices.CompositeUI.EventBroker to handle event subscription and publication in our application. The way that works is that you add an attribute to your event, specifying a topic name, like this:

我们正在使用 Microsoft.Practices.CompositeUI.EventBroker 来处理我们应用程序中的事件订阅和发布。有效的方法是向事件添加一个属性,指定一个主题名称,如下所示:

[EventPublication("example", PublicationScope.Global)]
public event EventHandler Example;

then you add another attribute to your handler, with the same topic name, like this:

然后向处理程序添加另一个属性,具有相同的主题名称,如下所示:

[EventSubscription("example", ThreadOption.Publisher)]
public void OnExample(object sender, EventArgs e)
{
    ...
}

Then you pass your objects to an EventInspector which matches everything up.

然后将对象传递给匹配所有内容的 EventInspector。

We need to debug this, so we're trying to create a debug class that subscribes to allthe events. I can get a list of all the topic names... but only at runtime. So I need to be able to add attributes to a method at runtime, before we pass our debug object to the EventInspector.

我们需要调试这个,所以我们试图创建一个订阅所有事件的调试类。我可以获得所有主题名称的列表......但仅限于运行时。因此,在我们将调试对象传递给 EventInspector 之前,我需要能够在运行时向方法添加属性。

How do I add attributes to a method at runtime?

如何在运行时向方法添加属性?

采纳答案by Bogdan Maxim

What you are trying to achieve is quite complicated, so I will try to provide something just to get you started. This is what I think you would need to combine in order to achieve something:

您要实现的目标非常复杂,因此我将尝试提供一些内容来帮助您入门。这是我认为您需要结合才能实现某些目标的内容:

  1. Define an abstract class AbstractEventDebugger, with a method Searchthat searches all of the eventmembers, and registers them with the EventInspector. Also, define a method IdentifyEventthat will allow you to identify the event that has called it (this depends on you - what parameters will have, etc.).
  2. Define a dynamic typeusing TypeBuilder(as described here), that inherits from your class. This class would be the class of your debuggerobject.
  3. Attach the Handlers to your class using Reflection.Emit.MethodBuilder(see here), which will be calling the IdentifyEventmethod from the parent class and,
  4. Reflection.Emitthe attributes on the handlers using CustomAttributeBuilderclass (see here).
  5. Create an instance of your dynamicclass and send it to the EventInspector.
  6. Fire it up :)
  1. 定义一个抽象类AbstractEventDebugger,使用Search搜索所有event成员的方法,并将它们注册到 EventInspector。此外,定义一个方法IdentifyEvent,允许您识别调用它的事件(这取决于您 - 将具有哪些参数等)。
  2. 定义dynamic type使用TypeBuilder(如描述在这里从你的类),继承。这个类将是你的debugger对象的类。
  3. 使用Reflection.Emit.MethodBuilder(参见此处)将处理程序附加到您的类,这将从IdentifyEvent父类调用该方法,并且,
  4. Reflection.Emit使用CustomAttributeBuilder类的处理程序的属性(请参阅此处)。
  5. 创建您的dynamic类的实例并将其发送到 EventInspector。
  6. 燃烧起来;动起来 :)

Hereis a sample on how to create a method that calls something (Actually it's the classic "Hello world").

是一个关于如何创建一个调用某些东西的方法的示例(实际上它是经典的“Hello world”)。

You will need to do a lot of tweaking in order to get it done well, but you will learn a lot about reflection.

你需要做很多调整才能把它做好,但你会学到很多关于反射的知识。

Good luck!

祝你好运!

回答by Marc Gravell

Attributes are a compile-time feature (unless you are dealing with ComponentModel - but I suspect it is using reflection). As such, you cannot add attributes at runtime. It would a similar question to "how do I add an extra method to a type at runtime?". In regular C# / .NET (pre-DLR), you can't.

属性是一个编译时功能(除非您正在处理 ComponentModel - 但我怀疑它正在使用反射)。因此,您不能在运行时添加属性。这将是一个类似于“如何在运行时向类型添加额外方法?”的问题。在常规 C#/.NET(前 DLR)中,你不能。

回答by k?e?m?p? ?

You need to delve into the world of the DynamicMethod. However, as you need then to know MSIL, I really suggest you think hard about your architecture.

您需要深入了解DynamicMethod. 但是,由于您需要了解 MSIL,我真的建议您仔细考虑一下您的架构。

回答by Mike Minutillo

The EventInspector uses EventTopics (which are stored in the WorkItem) to do all the heavy lifting. Each EventTopic object has access to a TraceSource called

EventInspector 使用 EventTopics(存储在 WorkItem 中)来完成所有繁重的工作。每个 EventTopic 对象都可以访问名为的 TraceSource

Microsoft.Practices.CompositeUI.EventBroker.EventTopic

Microsoft.Practices.CompositeUI.EventBroker.EventTopic

Which you can enable in your app.config file like this:

您可以在 app.config 文件中启用它,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <switches>
            <add name="Microsoft.Practices.CompositeUI.EventBroker.EventTopic" value="All" />
        </switches>
    </system.diagnostics>
</configuration>

This should make plenty of useful messages get routed to your debug window in Visual Studio. If you want to go beyond the VS debug window you have plenty of options. I'd recommend checking out the following article:

这应该会使大量有用的消息路由到 Visual Studio 中的调试窗口。如果你想超越 VS 调试窗口,你有很多选择。我建议查看以下文章:

Code Instrumentation with TraceSource My Persoanl Vade Mecum

使用 TraceSource 进行代码检测 My Persoanl Vade Mecum