.NET 属性 : Why does GetCustomAttributes() make a new attribute instance every time?

标签 .net performance attributes

所以我在 .NET 中使用了更多的属性,并意识到每次调用 Type.GetCustomAttributes() 都会创建我的属性的一个新实例。这是为什么?我认为属性实例基本上是一个单例每个成员信息,有 1 个实例绑定(bind)到类型、PropertyInfo 等...

这是我的测试代码:

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();
    }
}
}

现在,如果我要实现属性,我希望输出是:
Created MyAttrib instance
Getting attributes for MyClass.
Getting attributes for MyClass.
a1

“类加载器”(对不起,我有更多的 Java 背景,不是 100% 确定 .net 如何加载其类型)将编译 MyClass,并创建 MyAttribAttribute 的实例,并将它们一起存储在某个地方。 (如果这是 Java,可能是堆中的 Perm Gen)然后对 GetCustomAttributes() 的 2 次调用将返回相同的较早创建的实例。

但实际输出是:
Getting attributes for MyClass.
Created MyAttrib instance
Getting attributes for MyClass.
Created MyAttrib instance
SetOnClass

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

任何人都有任何想法为什么它是这样设计的?

我完全关心的原因是因为我创建了一个内部保存一些验证信息的自定义属性,所以在属性中我基本上有一个“private bool Validated”,我设置为 true。验证的东西需要一段时间,所以我不想每次都运行它。现在的问题是,由于每次我获取属性时它都会创建一个新的属性实例,因此 Validated 始终为“假”。

最佳答案

属性不作为对象存储在内存中,它们仅作为元数据存储在程序集中。当您查询它时,它将被构造并返回,并且通常属性是一次性对象,因此运行时保留它们以防万一您再次需要它们可能会浪费大量内存。

简而言之,您需要找到另一种方式来存储您的共享信息。

这是documentation关于属性。

关于.NET 属性 : Why does GetCustomAttributes() make a new attribute instance every time?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/417275/

相关文章:

c# - 在 ASP.NET 页面加载时运行 JavaScript 代码

.net - 引用程序集中的扩展方法?

java - 基于long值的HashMap,get/put o(1)?

sql-server - SQL Server 中的 'BETWEEN' 函数是否非常昂贵?

python 如何使用 setattr 或 exec 创建私有(private)类变量?

python - 执行 `func = func.__call__` 时 Python 会发生什么?

.net - 存在哪些 CLR/.NET 字节码工具?

c# - 如何在 Windows 中获取当前用户登录 session 的唯一 ID - c#

performance - 小阵列最快的偏移读取

javascript - 如何将 onchange 属性添加到 JavaScript 生成的复选框(在选中/取消选中时触发)?