.NET Attributes: Why does GetCustomAttributes() make a new attribute instance every time?(.NET 属性:为什么 GetCustomAttributes() 每次都创建一个新的属性实例?)
问题描述
所以我在 .NET 中使用了更多属性,并意识到每次调用 Type.GetCustomAttributes() 都会创建我的属性的一个新实例.这是为什么?我认为属性实例基本上是一个单例每个成员信息,有 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...
这是我的测试代码:
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,可能是堆中的 Perm Gen)对 GetCustomAttributes() 的 2 次调用将返回相同的早期创建的实例.
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?
我完全关心的原因是因为我创建了一个内部保存一些验证信息的自定义属性,所以在属性中我基本上有一个private bool Validated",我将其设置为 true.验证的东西需要一段时间,所以我不想每次都运行它.现在的问题是,因为每次我获取属性时它都会创建一个新的属性实例,所以 Validated 总是假".
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
);
?
这篇关于.NET 属性:为什么 GetCustomAttributes() 每次都创建一个新的属性实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:.NET 属性:为什么 GetCustomAttributes() 每次都创建一个新的属性实例?
- 使用 rss + c# 2022-01-01
- 在 LINQ to SQL 中使用 contains() 2022-01-01
- Windows 喜欢在 LINUX 中使用 MONO 进行服务开发? 2022-01-01
- C# 通过连接字符串检索正确的 DbConnection 对象 2022-01-01
- 在 C# 中异步处理项目队列 2022-01-01
- Azure Active Directory 与 MVC,客户端和资源标识同一 2022-01-01
- 为什么 C# 中的堆栈大小正好是 1 MB? 2022-01-01
- 是否可以在 .Net 3.5 中进行通用控件? 2022-01-01
- CanBeNull和ReSharper-将其用于异步任务? 2022-01-01
- 带问号的 nvarchar 列结果 2022-01-01