.NET属性:为什么GetCustomAttributes()使每一次新的属性实例?属性、实例、NET、GetCustomAttributes

2023-09-02 21:47:22 作者:东风敬我桃花酒

所以我玩弄多一点,在.NET中的属性,并意识到每次调用Type.GetCustomAttributes()创建了我的属性的新实例。这是为什么?我会认为属性实例将基本上是个单每的MemberInfo,1实例绑定类型,的PropertyInfo,等等...

So I was playing around a little more with attributes in .NET, and realized that every call to Type.GetCustomAttributes() creates a new instance of my attribute. Why is that? I would think that the attribute instance would basically be a singleton-per-MemberInfo, with 1 instance bound to the Type, PropertyInfo, etc...

下面是我的测试code:

Here is my test code:

using System;

namespace AttribTest
{
[AttributeUsage(AttributeTargets.Class)]
class MyAttribAttribute : Attribute
{
	public string Value { get; set; }

	public MyAttribAttribute()
		: base()
	{
		Console.WriteLine("Created MyAttrib instance");
	}
}

[MyAttrib(Value = "SetOnClass")]
class MyClass
{
}

class Program
{
	static void Main(string[] args)
	{
		Console.WriteLine("Getting attributes for MyClass.");
		object[] a = typeof(MyClass).GetCustomAttributes(false);
		((MyAttribAttribute)a[0]).Value = "a1";

		Console.WriteLine("Getting attributes for MyClass.");
		a = typeof(MyClass).GetCustomAttributes(false);
		Console.WriteLine(((MyAttribAttribute)a[0]).Value);

		Console.ReadKey();
	}
}
}

现在,如果的 I 的是实现属性,我希望的输出是:

Now if I were to implement attributes, I would expect the output to be:

Created MyAttrib instance
Getting attributes for MyClass.
Getting attributes for MyClass.
a1

当类加载器(对不起,我有更多的Java的背景下,不是100%肯定.NET如何加载其类型)将编译MyClass的,创造MyAttribAttribute的一个实例,并将其存储起来的地方。 (可能是烫发根堆,如果这是Java)的2调用GetCustomAttributes(),然后将刚刚返回同一个先前创建的实例。

Where the "class loader" (sorry, I have more of a Java background, not 100% sure how .net loads its types) would compile MyClass, and create an instance of MyAttribAttribute, and store them together somewhere. (probably the Perm Gen in the heap if this were Java) The 2 calls to GetCustomAttributes() would then just return the same earlier created instance.

但是实际的输出是:

Getting attributes for MyClass.
Created MyAttrib instance
Getting attributes for MyClass.
Created MyAttrib instance
SetOnClass

所以......为什么呢?这似乎是创建所有这些对象的新实例每次调用是有点过分,而对于性能/内存管理不好。有没有什么办法总能得到相同的实例一遍又一遍?

So... why? It seems like creating a new instance of all these objects for every call is a bit excessive, and not good for performance/memory management. Is there any way to always get the same instance over and over?

任何人有任何想法,为什么它被设计成这样?

Anyone have any ideas why it was designed this way?

我不在乎一切的原因是因为我做了一个自定义属性的内部保存了一些验证信息,所以在属性我基本上有一个私人布尔验证,我设置为true。验证的东西需要一段时间,所以我不希望每次都运行它。现在的问题是,由于它创建的属性的新实例每次我得到的属性时,验证始终是假的。

The reason I care at all is because I made a custom attribute that internally holds some validation information, so in the Attribute I basically have a "private bool Validated" that I set to true. The validation stuff takes a while, so I don't want to run it every time. Now the problem is that since it creates a new instance of the attribute each time I get the attributes, Validated is always "false".

推荐答案

对象创建便宜。

如果你有类似的属性。

public class MyAttribute : Attribute {
    public virtual string MyText { get; set; }
}

和其应用的一类像

[MyAttribute(MyText="some text")]
public class MyClass {
}

和您检索一个像

var attr =
    typeof(MyClass).GetCustomAttributes(typeof(MyAttribute), false)
    .Cast<MyAttribute>().Single();

和你设置它的一些属性,如

and you set some properties on it like

attr.MyText = "not the text we started with";

什么的应的发生,并且什么的将会的发生,下次你叫

what should happen, and what would happen, the next time you called

Console.WriteLine(
    typeof(MyClass).GetCustomAttributes(typeof(MyAttribute), false)
    .Cast<MyAttribute>().Single().Name
);

 
精彩推荐
图片推荐