.NET属性:为什么GetCustomAttributes()每次都会创建一个新的属性实例?

StackOverflow https://stackoverflow.com/questions/417275

  •  03-07-2019
  •  | 
  •  

所以我在.NET中使用属性更多地玩,并意识到每次调用Type.GetCustomAttributes()都会创建一个属性的新实例。这是为什么?我认为属性实例基本上是一个single-each-MemberInfo,其中一个实例绑定到Type,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总是“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();

并在其上设置了一些属性,如

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

应该发生什么, 会发生什么,下次你打电话

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

其他提示

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

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

以下是文档属性。

这是因为属性保存在元数据中。 属性应该用于诸如“用户友好的属性名称”等信息......

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top