当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《.NET属性:为什么GetCustomAttributes()每次都会创建一个新的属性实例?》经验,为你挑选了2个好方法。

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

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

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

我之所以关心的原因是因为我创建了一个内部保存一些验证信息的自定义属性,所以在属性中我基本上有一个"私有bool验证"我设置为true.验证的东西需要一段时间,所以我不想每次都运行它.现在的问题是,因为每次获取属性时它都会创建一个新的属性实例,Validated总是"false".



1> angry person..:

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

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

这是关于属性的[MSDN](http://msdn.microsoft.com/en-us/library/5x6cd29c ( VS.71%29.aspx)页面.



2> yfeldblum..:

对象创建很便宜.

如果你有一个像这样的属性

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().Single();

你在它上面设置了一些属性

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

什么应该发生的,什么发生,下一次调用时

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


我有一个属性验证日期大于DateTime.Now ...如果每次调用GetCustomAttributes时都没有初始化它将无法工作...因为它不会验证日期反对现在它将验证它反对系统启动的时间......
推荐阅读
有风吹过best
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有