C# 自定义属性的构造函数何时运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1168535/
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
When is a custom attribute's constructor run?
提问by devoured elysium
When is it run? Does it run for each object to which I apply it, or just once? Can it do anything, or its actions are restricted?
什么时候运行?它是为我应用它的每个对象运行,还是只运行一次?它可以做任何事情,或者它的行动受到限制?
采纳答案by Fredrik M?rk
When is the constructor run? Try it out with a sample:
构造函数什么时候运行?用一个示例试试看:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Creating MyClass instance");
MyClass mc = new MyClass();
Console.WriteLine("Setting value in MyClass instance");
mc.Value = 1;
Console.WriteLine("Getting attributes for MyClass type");
object[] attributes = typeof(MyClass).GetCustomAttributes(true);
}
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute()
{
Console.WriteLine("Running constructor");
}
}
[MyAttribute]
class MyClass
{
public int Value { get; set; }
}
And what is the output?
输出是什么?
Creating MyClass instance
Setting value in MyClass instance
Getting attributes for MyClass type
Running constructor
So, the attribute constructor is run when we start to examine the attribute. Note that the attribute is fetched from the type, not the instance of the type.
因此,当我们开始检查属性时,就会运行属性构造函数。请注意,属性是从类型中获取的,而不是类型的实例。
回答by Sam Harwell
The metadata in the executable or DLL stores:
可执行文件或 DLL 中的元数据存储:
- A metadata tokenindicating the constructor to call
- The arguments
- 一个令牌元数据指示构造函数调用
- 论据
When I get to that section of my CLI implementation, I plan to lazy-call the constructor the first time GetCustomAttributes()
is called for the ICustomAttributeProvider
. If a particular attribute type is requested, I'll only construct the ones required to return that type.
当我到达 CLI 实现的那部分时,我计划在第一次GetCustomAttributes()
为ICustomAttributeProvider
. 如果请求特定的属性类型,我将只构建返回该类型所需的类型。
回答by Christian Klauser
Set a debugger break-point inside an attribute constructor and write some reflection code that reads those attributes. You'll notice that the attribute objects won't be created until they are returned from the relfection API. Attributes are per class. They are part of the meta data.
在属性构造函数中设置调试器断点并编写一些读取这些属性的反射代码。您会注意到,在从 relfection API 返回属性对象之前,不会创建它们。属性是每个类。它们是元数据的一部分。
Have a look at this:
看看这个:
Program.cs
程序.cs
using System;
using System.Linq;
[My(15)]
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Program started");
var ats =
from a in typeof(Program).GetCustomAttributes(typeof(MyAttribute), true)
let a2 = a as MyAttribute
where a2 != null
select a2;
foreach(var a in ats)
Console.WriteLine(a.Value);
Console.WriteLine("Program ended");
Console.ReadLine();
}
}
MyAttribute.cs
我的属性文件
using System;
[AttributeUsage(validOn : AttributeTargets.Class)]
public class MyAttribute : Attribute
{
public MyAttribute(int x)
{
Console.WriteLine("MyAttribute created with {0}.", x);
Value = x;
}
public int Value { get; private set; }
}
Result
结果
Program started
MyAttribute created with 15.
15
Program ended
But don't worry about the performance of attribute constructors. They are the fastest part of reflection :-P
但是不要担心属性构造函数的性能。它们是反射最快的部分:-P
回答by Roman Starkov
The constructor is run every timethe GetCustomAttributes
is invoked, or whenever some other code invokes the constructor directly (not that there's a good reason to do so, but it's not impossible either).
构造函数运行每次将GetCustomAttributes
被调用时,或当一些其他的代码直接调用构造函数(不是有一个很好的理由这样做,但也不是不可能的)。
Note that at least in .NET 4.0, the attribute instances are not cached; a fresh instance is constructed every time GetCustomAttributes
is called:
请注意,至少在 .NET 4.0 中,不会缓存属性实例;每次GetCustomAttributes
调用时都会构造一个新实例:
[Test]
class Program
{
public static int SomeValue;
[Test]
public static void Main(string[] args)
{
var method = typeof(Program).GetMethod("Main");
var type = typeof(Program);
SomeValue = 1;
Console.WriteLine(method.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "1"
SomeValue = 2;
Console.WriteLine(method.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "2"
SomeValue = 3;
Console.WriteLine(type.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "3"
SomeValue = 4;
Console.WriteLine(type.GetCustomAttributes(false)
.OfType<TestAttribute>().First().SomeValue);
// prints "4"
Console.ReadLine();
}
}
[AttributeUsage(AttributeTargets.All)]
class TestAttribute : Attribute
{
public int SomeValue { get; private set; }
public TestAttribute()
{
SomeValue = Program.SomeValue;
}
}
It is not the best idea to have attributes behave like this, of course. At the very least, note that GetCustomAttributes
is notdocumented to behave like this; in fact, what happens in the above program is not specified in the documentation.
当然,让属性表现得像这样并不是最好的主意。最起码,请注意,GetCustomAttributes
是没有记录在案,以这样的表现; 事实上,上述程序中发生的事情并没有在文档中说明。