Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Attribute bieten eine Möglichkeit zum Zuordnen von Informationen mit Code auf deklarative Weise. Sie können auch ein wiederverwendbares Element bereitstellen, das auf verschiedene Ziele angewendet werden kann. Sehen Sie sich das ObsoleteAttribute an. Sie kann auf Klassen, Strukturen, Methoden, Konstruktoren und vieles mehr angewendet werden. Es deklariert , dass das Element veraltet ist. Dann liegt es am C#-Compiler, nach diesem Attribut zu suchen und daraufhin eine Aktion auszuführen.
In diesem Lernprogramm erfahren Sie, wie Sie Ihrem Code Attribute hinzufügen, eigene Attribute erstellen und verwenden und wie Sie einige in .NET integrierte Attribute verwenden.
Voraussetzungen
Sie müssen Ihren Computer so einrichten, dass .NET ausgeführt wird. Die Installationsanweisungen finden Sie auf der .NET-Downloadseite . Sie können diese Anwendung unter Windows, Ubuntu Linux, macOS oder in einem Docker-Container ausführen. Sie müssen Ihren bevorzugten Code-Editor installieren. In den folgenden Beschreibungen wird Visual Studio Code verwendet, bei dem es sich um einen plattformübergreifenden Open Source-Editor handelt. Sie können jedoch alle Tools verwenden, mit denen Sie vertraut sind.
Erstellen der App
Nachdem Sie nun alle Tools installiert haben, erstellen Sie eine neue .NET-Konsolen-App. Um den Befehlszeilengenerator zu verwenden, führen Sie den folgenden Befehl in Ihrer bevorzugten Shell aus:
dotnet new console
Mit diesem Befehl werden minimalistische .NET-Projektdateien erzeugt. Führen Sie dotnet restore
aus, um die Abhängigkeiten wiederherzustellen, die zum Kompilieren dieses Projekts erforderlich sind.
Sie müssen dotnet restore
nicht ausführen, da der Befehl implizit von allen Befehlen ausgeführt wird, die eine Wiederherstellung erfordern. Zu diesen zählen z. B. dotnet new
, dotnet build
, dotnet run
, dotnet test
, dotnet publish
und dotnet pack
. Verwenden Sie die Option --no-restore
, um die implizite Wiederherstellung zu deaktivieren.
In bestimmten Fällen eignet sich der dotnet restore
-Befehl dennoch. Dies ist etwa bei Szenarios der Fall, in denen die explizite Wiederherstellung sinnvoll ist. Beispiele hierfür sind Continuous Integration-Builds in Azure DevOps Services oder Buildsysteme, die den Zeitpunkt für die Wiederherstellung explizit steuern müssen.
Informationen zum Verwalten von NuGet-Feeds finden Sie in der dotnet restore
Dokumentation.
Verwenden Sie dotnet run
zum Ausführen des Programms . Es sollte „Hello, World“ auf der Konsole ausgegeben werden.
Hinzufügen von Attributen zu Code
In C# sind Attribute Klassen, die von der Attribute
Basisklasse erben. Jede Klasse, die von Attribute
erbt, kann als eine Art "Tag" für andere Codeabschnitte verwendet werden. Es gibt zum Beispiel ein Attribut namens ObsoleteAttribute
. Dieses Attribut signalisiert, dass Code veraltet ist und nicht mehr verwendet werden sollte. Sie platzieren dieses Attribut z. B. mithilfe von eckigen Klammern auf einer Klasse.
[Obsolete]
public class MyClass
{
}
Auch wenn die Klasse als ObsoleteAttribute
benannt ist, ist es im Code nur erforderlich, [Obsolete]
zu verwenden. Der größte C#-Code folgt dieser Konvention. Sie können den vollständigen Namen [ObsoleteAttribute]
verwenden, wenn Sie dies auswählen.
Wenn Sie eine Klasse als veraltet markieren, ist es ratsam, einige Informationen darüber bereitzustellen, warum sie veraltet sind und/oder was stattdessen verwendet werden soll. Sie fügen einen Zeichenfolgenparameter in das veraltete Attribut ein, um diese Erklärung bereitzustellen.
[Obsolete("ThisClass is obsolete. Use ThisClass2 instead.")]
public class ThisClass
{
}
Die Zeichenfolge wird als Argument an einen ObsoleteAttribute
Konstruktor übergeben, als ob Sie schreiben var attr = new ObsoleteAttribute("some string")
.
Parameter für einen Attributkonstruktor sind auf einfache Typen/Literale beschränkt: bool, int, double, string, Type, enums, etc
und Arrays dieser Typen.
Sie können keinen Ausdruck oder eine Variable verwenden. Sie können positions- oder benannte Parameter verwenden.
Ein eigenes Attribut erstellen
Sie erstellen ein Attribut, indem Sie eine neue Klasse definieren, die von der Attribute
Basisklasse erbt.
public class MySpecialAttribute : Attribute
{
}
Mit dem vorherigen Code können Sie [MySpecial]
(oder [MySpecialAttribute]
) als Attribut an anderer Stelle in der Codebasis verwenden.
[MySpecial]
public class SomeOtherClass
{
}
Attribute in der .NET-Basisklassenbibliothek wie ObsoleteAttribute
lösen bestimmte Verhaltensweisen innerhalb des Compilers aus. Jedes von Ihnen erstellte Attribut fungiert jedoch nur als Metadaten und führt nicht zu code innerhalb der auszuführenden Attributklasse. Es liegt an Ihnen, auf diese Metadaten an anderer Stelle in Ihrem Code zu reagieren.
Es gibt hierbei ein Problem, das beachtet werden muss. Wie bereits erwähnt, können nur bestimmte Typen bei Verwendung von Attributen als Argumente übergeben werden. Beim Erstellen eines Attributtyps verhindert der C#-Compiler jedoch nicht, dass Sie diese Parameter erstellen. Im folgenden Beispiel haben Sie ein Attribut mit einem Konstruktor erstellt, der ordnungsgemäß kompiliert wird.
public class GotchaAttribute : Attribute
{
public GotchaAttribute(Foo myClass, string str)
{
}
}
Sie können diesen Konstruktor jedoch nicht mit Attributsyntax verwenden.
[Gotcha(new Foo(), "test")] // does not compile
public class AttributeFail
{
}
Der vorangehende Code verursacht einen Compilerfehler wie Attribute constructor parameter 'myClass' has type 'Foo', which is not a valid attribute parameter type
Wie man die Verwendung von Attributen einschränkt
Attribute können für die folgenden "Ziele" verwendet werden. In den obigen Beispielen wurde die Verwendung für Klassen gezeigt, aber Attribute können auch für folgende Elemente verwendet werden:
- Versammlung
- Klasse
- Konstruktor
- Delegieren
- Enumeration
- Ereignis
- Feld
- GenerischerParameter
- Schnittstelle
- Methode
- Modul
- Parameter
- Eigentum
- ReturnValue
- Struktur
Wenn Sie eine Attributklasse erstellen, erlaubt C# Ihnen standardmäßig, dieses Attribut für alle möglichen Ziele zu verwenden. Wenn Sie Ihr Attribut auf bestimmte Ziele beschränken möchten, können Sie dies mithilfe der AttributeUsageAttribute
Attributklasse tun. Ganz richtig, ein Attribut für ein Attribut!
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)]
public class MyAttributeForClassAndStructOnly : Attribute
{
}
Wenn Sie versuchen, das obige Attribut auf etwas zu setzen, das keine Klasse oder Struktur ist, erhalten Sie einen Compilerfehler wie Attribute 'MyAttributeForClassAndStructOnly' is not valid on this declaration type. It is only valid on 'class, struct' declarations
public class Foo
{
// if the below attribute was uncommented, it would cause a compiler error
// [MyAttributeForClassAndStructOnly]
public Foo()
{ }
}
Verwenden von Attributen, die an ein Codeelement angefügt sind
Attribute fungieren als Metadaten. Ohne irgendeine äußere Kraft tun sie eigentlich nichts.
Um Attribute zu finden und zu bearbeiten, ist eine Reflexion erforderlich. Mit Reflection können Sie Code in C# schreiben, der anderen Code untersucht. Sie können z. B. Reflection verwenden, um Informationen zu einer Klasse abzurufen(fügen Sie am Anfang Ihres Codes hinzu using System.Reflection;
):
TypeInfo typeInfo = typeof(MyClass).GetTypeInfo();
Console.WriteLine("The assembly qualified name of MyClass is " + typeInfo.AssemblyQualifiedName);
Damit wird etwa Folgendes ausgegeben: The assembly qualified name of MyClass is ConsoleApplication.MyClass, attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Nachdem Sie ein Objekt (oder ein TypeInfo
MemberInfo
, FieldInfo
oder ein anderes Objekt) haben, können Sie die GetCustomAttributes
Methode verwenden. Diese Methode gibt eine Auflistung von Attribute
Objekten zurück. Sie können auch GetCustomAttribute
verwenden und einen Attributtyp angeben.
Hier ist ein Beispiel für die Verwendung von GetCustomAttributes
in einer MemberInfo
-Instanz für MyClass
(bei der wir zuvor gesehen haben, dass darauf ein [Obsolete]
-Attribut vorhanden ist).
var attrs = typeInfo.GetCustomAttributes();
foreach(var attr in attrs)
Console.WriteLine("Attribute on MyClass: " + attr.GetType().Name);
Dies wird in der Konsole ausgegeben: Attribute on MyClass: ObsoleteAttribute
. Versuchen Sie, weitere Attribute zu MyClass
hinzuzufügen.
Es ist wichtig, darauf hinzuweisen, dass diese Attribute
-Objekte verzögert instanziiert werden. Das heißt, sie werden nicht instanziiert, bis Sie GetCustomAttribute
oder GetCustomAttributes
verwenden. Sie werden außerdem jedes Mal instanziiert. Wenn GetCustomAttributes
zweimal nacheinander aufgerufen wird, gibt es zwei verschiedene Instanzen von ObsoleteAttribute
zurück.
Allgemeine Attribute in der Laufzeit
Attribute werden von vielen Tools und Frameworks verwendet. NUnit verwendet Attribute wie [Test]
und [TestFixture]
die von der NUnit-Testläuferin verwendet werden. ASP.NET MVC verwendet Attribute wie [Authorize]
und stellt ein Aktionsfilter-Framework bereit, um querschnittliche Anliegen bei MVC-Aktionen auszuführen.
PostSharp verwendet die Attributsyntax, um die seitenorientierte Programmierung in C# zu ermöglichen.
Hier sind einige wichtige Attribute, die in die .NET Core-Basisklassenbibliotheken integriert sind:
-
[Obsolete]
. Diese wurde in den obigen Beispielen verwendet und lebt imSystem
Namespace. Es ist hilfreich, deklarative Dokumentationen zu einer sich ändernden Codebasis bereitzustellen. Eine Nachricht kann in Form einer Zeichenfolge bereitgestellt werden, und ein anderer boolescher Parameter kann verwendet werden, um von einer Compilerwarnung zu einem Compilerfehler zu eskalieren. -
[Conditional]
. Dieses Attribut befindet sich imSystem.Diagnostics
Namespace. Dieses Attribut kann auf Methoden (oder Attributklassen) angewendet werden. Sie müssen eine Zeichenfolge an den Konstruktor übergeben. Wenn diese Zeichenfolge keiner Direktive entspricht#define
, entfernt der C#-Compiler alle Aufrufe dieser Methode (aber nicht die Methode selbst). In der Regel verwenden Sie diese Technik für Debuggingzwecke (Diagnose). -
[CallerMemberName]
. Dieses Attribut kann für Parameter verwendet werden und befindet sich imSystem.Runtime.CompilerServices
Namespace.CallerMemberName
ist ein Attribut, das zum Einfügen des Namens der Methode verwendet wird, die eine andere Methode aufruft. Es ist eine Möglichkeit, "magische Zeichenfolgen" bei der Implementierung von INotifyPropertyChanged in verschiedenen UI-Frameworks zu beseitigen. Beispiel:
public class MyUIClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string propertyName = default!)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string? _name;
public string? Name
{
get { return _name;}
set
{
if (value != _name)
{
_name = value;
RaisePropertyChanged(); // notice that "Name" is not needed here explicitly
}
}
}
}
Im obigen Code müssen Sie nicht über eine Literalzeichenfolge "Name"
verfügen. Die Verwendung CallerMemberName
verhindert Tippfehler und sorgt auch für eine reibungslosere Umgestaltung/Umbenennung. Attribute bringen deklarative Macht für C# mit, sie sind jedoch eine Metadatenform von Code und handeln nicht selbst.