.NET Attribute: Warum GetCustomAttributes tut () machen ein neues Attribut Instanz jedes Mal?

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

  •  03-07-2019
  •  | 
  •  

Frage

Also ich um ein wenig mehr mit Attributen in .NET spiele, und erkannte, dass jeder Anruf zu Type.GetCustomAttributes () eine neue Instanz von meinem Attribute erstellt. Warum ist das so? Ich würde denken, dass das Attribut Instanz im Grunde ein Singleton-per-Member, mit 1 Instanz an den Typ gebunden sein würde, Propertyinfo, etc ...

Hier ist mein Testcode:

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

Nun, wenn I waren Attribute zu implementieren, würde ich die Ausgabe erwarten zu sein:

Created MyAttrib instance
Getting attributes for MyClass.
Getting attributes for MyClass.
a1

Wenn der „Class-Loader“ (sorry, ich habe mehr von einem Java-Hintergrund, nicht 100% sicher, wie .net seine Typen lädt) würde MyClass kompilieren, und eine Instanz von MyAttribAttribute erstellen und speichert sie irgendwo zusammen. (Wahrscheinlich das Perm Gen in der Halde wenn dies Java) Die 2 Anrufe GetCustomAttributes () würde dann wieder nur die gleiche zuvor erstellte Instanz.

Aber die tatsächliche Ausgabe lautet:

Getting attributes for MyClass.
Created MyAttrib instance
Getting attributes for MyClass.
Created MyAttrib instance
SetOnClass

So ... warum? Es scheint wie eine neue Instanz all diese Objekte erstellen für jeden Anruf ein bisschen zu groß ist, und nicht gut für die Leistung / Speicherverwaltung. Gibt es eine Möglichkeit die gleiche Instanz immer und immer immer zu bekommen?

Wer irgendwelche Ideen, warum es so entworfen wurde?

Der Grund, warum ich überhaupt interessiert, ist, weil ich ein Maß Attribut, das intern einige Validierungsinformationen hält, so in dem Attribut Ich habe im Grunde eine „private bool Validated“, die ich auf true gesetzt. Die Validierung Zeug dauert eine Weile, so will ich nicht jedes Mal ausgeführt werden. Das Problem ist jetzt, dass, da es sich um eine neue Instanz des Attributs jedes Mal erstellt ich die Attribute bekommen, Validated ist immer „false“.

War es hilfreich?

Lösung

Object-creation ist billig.

Wenn Sie hatte ein Attribut wie

public class MyAttribute : Attribute {
    public virtual string MyText { get; set; }
}

und wandte sie auf eine Klasse wie

[MyAttribute(MyText="some text")]
public class MyClass {
}

und Sie abgerufene ein wie

var attr =
    typeof(MyClass).GetCustomAttributes(typeof(MyAttribute), false)
    .Cast<MyAttribute>().Single();

und Sie setzen einige Eigenschaften auf wie es

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

was sollte geschehen, und was würde passieren, das nächste Mal aufgerufen

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

Andere Tipps

Attribute nicht als Objekte im Speicher gespeichert sind, sind sie nur als Metadaten in der Baugruppe gespeichert. Wenn Sie es abfragen, wird es gebaut und zurückgeschickt werden, und in der Regel Attribute sind Wegwerf-Objekte so für die Laufzeit, sie zu halten um für alle Fälle Sie sie wieder wahrscheinlich viel Speicher verschwenden würde brauchen würde.

Kurz gesagt, müssen Sie einen anderen Weg finden Ihre freigegebenen Informationen zu speichern.

Hier ist die Dokumentation auf Attribute.

Es ist, weil die Attribute in den Metadaten gespeichert werden. Attribute sollten für Informationen wie „benutzerfreundlichen Namen des Eigentums“, etc. verwendet werden ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top