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

.NET Attributes: Why does GetCustomAttributes() make a new attribute instance every time?(.NET 属性:为什么 GetCustomAttributes() 每次都创建一个新的属性实例?)
本文介绍了.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() 每次都创建一个新的属性实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
quot;Overflowquot; compiler error with -9223372036854775808L(编译器错误-9223372036854775808L(Q;溢出Q))
Visual Studio 2010 ReportViewer Assembly References(Visual Studio 2010 ReportViewer程序集引用)
Weird behaviour when I open a reportviewer in WPF(在WPF中打开报表查看器时出现奇怪的行为)
how do i pass parameters to aspnet reportviewer(如何将参数传递给aspnet report查看器)