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
How do I add attributes to a method at runtime?
提问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:
您要实现的目标非常复杂,因此我将尝试提供一些内容来帮助您入门。这是我认为您需要结合才能实现某些目标的内容:
- Define an abstract class
AbstractEventDebugger
, with a methodSearch
that searches all of theevent
members, and registers them with the EventInspector. Also, define a methodIdentifyEvent
that will allow you to identify the event that has called it (this depends on you - what parameters will have, etc.). - Define a
dynamic type
usingTypeBuilder
(as described here), that inherits from your class. This class would be the class of yourdebugger
object. - Attach the Handlers to your class using
Reflection.Emit.MethodBuilder
(see here), which will be calling theIdentifyEvent
method from the parent class and, Reflection.Emit
the attributes on the handlers usingCustomAttributeBuilder
class (see here).- Create an instance of your
dynamic
class and send it to the EventInspector. - Fire it up
:)
- 定义一个抽象类
AbstractEventDebugger
,使用Search
搜索所有event
成员的方法,并将它们注册到 EventInspector。此外,定义一个方法IdentifyEvent
,允许您识别调用它的事件(这取决于您 - 将具有哪些参数等)。 - 定义
dynamic type
使用TypeBuilder
(如描述在这里从你的类),继承。这个类将是你的debugger
对象的类。 - 使用
Reflection.Emit.MethodBuilder
(参见此处)将处理程序附加到您的类,这将从IdentifyEvent
父类调用该方法,并且, Reflection.Emit
使用CustomAttributeBuilder
类的处理程序的属性(请参阅此处)。- 创建您的
dynamic
类的实例并将其发送到 EventInspector。 - 燃烧起来;动起来
:)
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