Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 10 Weitere C#-Sprachfeatures
Pfeil 10.1 Implizit typisierte Variablen
Pfeil 10.2 Anonyme Typen
Pfeil 10.3 Lambda-Ausdrücke
Pfeil 10.3.1 Projektion und Prädikat
Pfeil 10.4 Erweiterungsmethoden
Pfeil 10.5 Partielle Methoden
Pfeil 10.5.1 Wo partielle Methoden eingesetzt werden
Pfeil 10.6 Operatorüberladung
Pfeil 10.6.1 Einführung
Pfeil 10.6.2 Die Syntax der Operatorüberladung
Pfeil 10.6.3 Die Operatorüberladungen im Projekt »GeometricObjectsSolution«
Pfeil 10.6.4 Die Operatoren »true« und »false« überladen
Pfeil 10.6.5 Benutzerdefinierte Konvertierungen
Pfeil 10.7 Indexer
Pfeil 10.7.1 Überladen von Indexern
Pfeil 10.7.2 Parameterbehaftete Eigenschaften
Pfeil 10.8 Attribute
Pfeil 10.8.1 Das »Flags«-Attribut
Pfeil 10.8.2 Benutzerdefinierte Attribute
Pfeil 10.8.3 Attribute auswerten
Pfeil 10.8.4 Festlegen der Assembly-Eigenschaften in »Assembly-Info.cs«
Pfeil 10.9 Dynamisches Binden
Pfeil 10.9.1 Eine kurze Analyse
Pfeil 10.9.2 Dynamische Objekte
Pfeil 10.10 Unsicherer (unsafe) Programmcode – Zeigertechnik in C#
Pfeil 10.10.1 Einführung
Pfeil 10.10.2 Das Schlüsselwort »unsafe«
Pfeil 10.10.3 Die Deklaration von Zeigern
Pfeil 10.10.4 Die »fixed«-Anweisung
Pfeil 10.10.5 Zeigerarithmetik
Pfeil 10.10.6 Der Operator »->«

Rheinwerk Computing - Zum Seitenanfang

10.8 AttributeZur nächsten Überschrift

Ein Attribut ist ein Feature von .NET, das einer Komponente deklarativ Zusatzinformationen bereitstellt oder einfach nur alleine durch seine Anwesenheit bestimmte Operationen ermöglicht oder gar steuert. Attribute gehören zu den Metadaten eines Programms und können zur Laufzeit ausgewertet werden.

Abbildung

Abbildung 10.1 Die Metadaten der Klasse »GeometricObject«

Anmerkung

Metadaten sind ein Pflichtbestandteil jeder .NET-Anwendung. Metadaten beschreiben sprachneutral die gesamte Struktur einer Assembly. Dazu gehören alle enthaltenen Typen, Methoden, Eigenschaften, Ereignisse, Konstruktoren, implementierte Interfaces usw. Zudem gehören zu den Metadaten auch weiter gehende Informationen, beispielsweise die Parameterlisten der Methoden einschließlich der Typangabe, die Sichtbarkeit der einzelnen Komponenten, Basisklassenangaben und viele andere Details. Der Vorteil ist, dass die Metadaten mit Hilfe der Reflection-API gelesen und ausgewertet werden können. Dazu muss noch

nicht einmal eine Klasse geladen, geschweige denn ein Objekt erstellt werden. Die IntelliSense-Liste greift zum Beispiel auch die Metadaten ab, woher sollte sie auch sonst die Informationen beziehen?

Sie können sich die Metadaten natürlich selber ansehen. Dazu stellt Visual Studio das Tool IL-Disassembler (ildasm.exe) zur Verfügung. Wenn Sie das Tool starten, müssen Sie nur die entsprechende EXE-Datei angeben, um die Metadaten zu sehen. Abbildung 10.1 zeigt exemplarisch das Kompilat der Datei GeometricObjects.exe des Beispielprogramms GeometricObjectsSolution_11.

Mit einem Attribut lässt sich das Laufzeitverhalten praktisch aller .NET-Komponenten beeinflussen: Assemblys, Klassen, Interfaces, Strukturen, Delegates, Enumerationen, Konstruktoren, Methoden, Eigenschaften, Parameter, Ereignisse, ja sogar die Rückgabewerte von Methoden.

Ein ganz typisches Attribut ist das SerializableAttribute. Es kann zum Beispiel mit einer Klasse, Enumeration, Struktur oder einem Delegaten verknüpft werden, z. B.:

[SerializableAttribute]
public class Circle { [...] }

Und wozu dient dieses Attribut? Die Antwort ist ganz einfach: Es legt allein mit seiner Anwesenheit fest, dass der Typ, hier Circle, binär serialisiert werden kann. Ist das Attribut nicht vorhanden, geht es nicht. Somit kommt diesem Attribut, wie vielen anderen auch, einzig und allein die Bedeutung einer booleschen Variablen zu, die true oder false gesetzt ist. Der Clou an der Sache ist, dass dazu nicht erst eine Klasse geladen oder gar ein Objekt erstellt werden muss. Stattdessen werden zur Laufzeit nur die Metadaten per Reflection ausgewertet, und die Information steht bereit, da Attribute in den Metadaten zu finden sind.

Basisklasse aller Attribute ist die abstrakte Klasse System.Attribute. Schaut man in die Online-Dokumentation zu Attribute, wird man feststellen, dass das .NET Framework sehr viele Attribute vordefiniert. Alle denkbaren Anforderungen werden damit sicherlich nicht abgedeckt, deshalb können Sie auch benutzerdefinierte Attribute entwickeln und dadurch die Flexibilität Ihrer Anwendung erhöhen.


Rheinwerk Computing - Zum Seitenanfang

10.8.1 Das »Flags«-AttributZur nächsten ÜberschriftZur vorigen Überschrift

Wir wollen uns die Wirkungsweise der Attribute exemplarisch am Attribut FlagsAttribute ansehen, das zum .NET Framework gehört und ausschließlich mit Enumerationen verknüpft werden kann. Mit dem Attribut lässt sich angeben, dass die Enumeration auch als Kombination von Bits, also ein Bit-Feld, aufgefasst werden kann.

Das wollen wir uns an einem Beispiel ansehen. Nehmen wir an, wir hätten eine benutzerdefinierte Enumeration namens Keys bereitgestellt, die drei Zustandstasten Shift, Strg und Alt beschreibt.

public enum Keys {
Shift = 1,
Ctrl = 2,
Alt = 4
}

Listing 10.37 Benutzerdefinierte Enumeration »Keys«

Die Enumerationsmitglieder sollen nun befähigt werden, als Bit-Feld interpretiert zu werden. Dazu wird das Attribut in eckige Klammern gefasst und vor der Definition der Enumeration angegeben.

[FlagsAttribute]
public enum Keys {
Shift = 1,
Ctrl = 2,
Alt = 4
}

Listing 10.38 Benutzerdefinierte Enumeration »Keys« mit dem »FlagsAttribute«

Nun können wir eine Variable vom Typ Keys deklarieren und ihr einen Wert zuweisen, der den Zustand der beiden gleichzeitig gedrückten Tasten Strg und Shift beschreibt. Beide Member verknüpfen wir mit dem |-Operator:

Keys tastenkombination = Keys.Ctrl | Keys.Shift;

Mit den bitweisen Operatoren kann nun geprüft werden, ob der Anwender eine bestimmte Taste oder gar Tastenkombination gedrückt hat.

Keys tastenkombination = Keys.Ctrl | Keys.Shift;
if ((tastenkombination & Keys.Alt) == Keys.Alt)
Console.WriteLine("Alt gedrückt");
else
Console.WriteLine("Alt nicht gedrückt");

Listing 10.39 Prüfen, ob eine bestimmte Tastenkombination gedrückt ist

Hier wird natürlich die Ausgabe lauten, dass die Alt-Taste nicht gedrückt ist, da die Variable tastenkombination die beiden Tasten Ctrl und Shift beschreibt.

Eine ähnliche Enumeration, die dann allerdings jede Taste der Tastatur beschreibt, gibt es übrigens auch im Namespace System.Windows.Forms.

Lassen wir uns nun den Inhalt der Variablen tastenkombination mit

Console.WriteLine(tastenkombination.ToString());

ausgeben, erhalten wir:

Shift, Ctrl

Hätten wir FlagsAttribute nicht gesetzt, würde die Ausgabe 3 lauten. Sie müssen berücksichtigen, dass die Mitglieder solchermaßen definierter Enumerationen Zweierpotenzen sind (also 1, 2, 4, 8, 16, 32, 64, ...). Alternativ sind auch hexadezimale Zahlenwerte zulässig.

Attribute setzen

Attributbezeichner enden immer mit dem Suffix Attribute. Wird ein Attribut mit einem Element verknüpft, darf auf das Suffix Attribute verzichtet werden. Bezogen auf unser Beispiel dürfen Sie also

[FlagsAttribute]
public enum Keys {
[...]
}

und

[Flags]
public enum Keys {
[...]
}

gleichwertig verwenden. Bemerkt die Laufzeit die Verknüpfung eines Attributs mit einem Element, sucht sie nach einer Klasse, die mit dem angegebenen Attributbezeichner übereinstimmt und gleichzeitig die Klasse Attribute ableitet, also beispielsweise nach einer Klasse namens Flags. Wird die Laufzeit nicht fündig, hängt sie automatisch das Suffix Attribute an den Bezeichner an und wiederholt seine Suche.

Sie können auch mehrere Attribute gleichzeitig setzen. Beispielsweise könnten Sie mit dem ObsoleteAttribute das Element zusätzlich als veraltet kennzeichnen, z. B.:

[FlagsAttribute]
[Obsolete("Diese Enumeration ist veraltet.");
public enum Keys {
[...]
}

Listing 10.40 Verknüpfung von »Keys« mit den Attributen »Obsolete« und »Flags«

Anmerkung

Innerhalb einer mit Flags verknüpften Enumeration können Sie zur Zuweisung auch die bereits in der Enumeration angegebenen Konstanten verwenden. Stellen Sie sich beispiels-

weise vor, in unserer Keys-Enumeration soll zusätzlich der Member All hinzugefügt werden, der alle anderen Enumerationsmember beschreibt. Sie können das wie folgt umsetzen:

[FlagsAttribute]
public enum Keys {
Shift = 1,
Ctrl = 2,
Alt = 4
All = Shift | Ctrl | Alt
}

Rheinwerk Computing - Zum Seitenanfang

10.8.2 Benutzerdefinierte AttributeZur nächsten ÜberschriftZur vorigen Überschrift

Attribute basieren auf Klassendefinitionen und können daher alle klassentypischen Elemente enthalten. Dazu gehören neben Konstruktoren auch Felder. Insbesondere diese beiden Elemente ermöglichen es, über ein Attribut dem attributierten Element Zusatzinformationen bereitzustellen. Wie das in der Praxis aussieht, wollen wir uns am Beispiel eines benutzerdefinierten Attributs verdeutlichen.

Obwohl das .NET Framework zahlreiche Attribute vordefiniert, können Sie auch für eigene Zwecke Attributklassen selber schreiben. Allerdings müssen Sie für die Auswertung des Attributs zur Laufzeit dann auch selber sorgen.

Drei Punkte müssen Sie beachten, um ein benutzerdefiniertes Attribut zu programmieren:

  • Der Definition eines benutzerdefinierten Attributs selbst geht immer die Definition des Attributs AttributeUsageAttribute voraus.
  • Die Klasse wird aus Attribute abgeleitet.
  • Dem Klassenbezeichner sollte das Suffix Attribute angehängt werden.

Lassen Sie uns an dieser Stelle exemplarisch ein eigenes Attribut erstellen, dessen Aufgabe es ist, sowohl den Entwickler einer Klasse oder Methode als auch dessen Personalnummer anzugeben. Das folgende Beispiel zeigt die noch unvollständige Definition der Attributklasse:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,
Inherited = false,
AllowMultiple = false)]
public class DeveloperAttribute : Attribute
{
[...]
}

Listing 10.41 Grundstruktur des benutzerdefinierten Attributs »DeveloperAttribute«

Die Voranstellung des Attributs AttributeUsage vor der Klasse legt elementare Eigenschaften der neuen Attributklasse fest. In diesem Zusammenhang sind drei Parameter besonders interessant:

  • AttributeTargets
  • Inherited
  • AllowMultiple

Während AttributeTargets angegeben werden muss, sind die beiden anderen Angaben optional.

AttributeTargets

Jedes Attribut kann sich nur auf bestimmte Codeelemente auswirken. Diese werden mit AttributeTargets bekannt gegeben. Das Attribut Flags kann beispielsweise mit Klassen, Enumerationen, Strukturen und Delegaten verknüpft werden. Man kann den Einsatz eines Attributs ebenso gut nur auf Methoden oder Felder beschränken. Es steht dabei immer folgende Frage im Vordergrund: Was soll das Attribut letztendlich bewirken, welche Elemente sollen über das Attribut beeinflusst werden?

AttributeTargets ist als Enumeration vordefiniert und weist seinerseits selbst das FlagsAttribute auf, um mehrere Zielelemente angeben zu können. In Tabelle 10.2 finden Sie alle möglichen Elemente, die generell mit Attributen verknüpft werden können.

Tabelle 10.2 Mitglieder der »AttributeTargets«-Enumeration

Mitglieder Beschreibung

All

Das Attribut gilt für jedes Element der Anwendung.

Assembly

Das Attribut gilt für die Assemblierung.

Class

Das Attribut gilt für die Klasse.

Constructor

Das Attribut gilt für den Konstruktor.

Delegate

Das Attribut gilt für den Delegate.

Enum

Das Attribut gilt für die Enumeration.

Event

Das Attribut gilt für das Ereignis.

Field

Das Attribut gilt für das Feld.

Interface

Das Attribut gilt für die Schnittstelle.

Method

Das Attribut gilt für die Methode.

Module

Das Attribut gilt für das Modul.

Parameter

Das Attribut gilt für den Parameter.

Property

Das Attribut gilt für die Property.

ReturnValue

Das Attribut gilt für den Rückgabewert.

Struct

Das Attribut gilt für die Struktur.

Im folgenden Listing sehen Sie den Teilausschnitt unseres benutzerdefinierten Attributs. Das Attribut kann entweder Klassen oder Methoden angeheftet werden.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DeveloperAttribute : Attribute { [...] }

Listing 10.42 Die Zielmember des Attributs angeben

Inherited

Eine Klasse kann ihre Mitglieder einer abgeleiteten Klasse vererben. Einem Entwickler stellt sich natürlich die Frage, ob das Attribut in den Vererbungsprozess mit einbezogen wird oder ob es Gründe gibt, es davon auszuschließen. Einem benutzerdefinierten Attribut teilen wir dies durch den booleschen Parameter Inherited mit, den wir optional AttributeUsageAttribute übergeben können. Standardmäßig ist der Wert auf true festgelegt. Demnach vererbt sich ein gesetztes Attribut in einer Vererbungshierarchie weiter.

AllowMultiple

In wohl eher seltenen Fällen kann es erforderlich sein, ein Attribut demselben Element mehrfach zuzuweisen. Diese Situation wäre denkbar, wenn man über das Attribut einem Element mehrere Feldinformationen zukommen lassen möchte. Dann muss man die mehrfache Anwendung eines Attributs explizit gestatten. Zur Lösung geben Sie den Parameter

AllowMultiple = true

an. Verzichten Sie auf diese Angabe, kann ein Attribut per Definition mit einem bestimmten Element nur einmal verknüpft werden.

Felder und Konstruktoren eines Attributs

Sie können in Attributklassen öffentliche Felder und Eigenschaften definieren, deren Daten an den Benutzer des Attributs weitergeleitet werden. Initialisiert werden die Felder über Konstruktoren.

Unser DeveloperAttribute soll nun um die beiden Felder Name und Identifier ergänzt werden. Das Feld Name wird beim Konstruktoraufruf initialisiert.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DeveloperAttribute : Attribute
{
public string Name { get; set; }
public int Identifier { get; set; }
public DeveloperAttribute(string name) {
Name = name;
}
}

Listing 10.43 Vollständiges benutzerdefiniertes Attribut

Der Konstruktor nimmt einen Parameter entgegen, nämlich den Wert für das Feld Name. Bevor Sie sich darüber Gedanken machen, wie man das Feld Identifier initialisiert, sehen Sie sich an, wie das Attribut auf eine Klasse angewendet wird:

[DeveloperAttribute("Meier")] 
public class Demo
{
[...]
}

Listing 10.44 Verwenden des benutzerdefinierten Attributs

Mit dieser Definition wird der Konstruktor unter Übergabe einer Zeichenfolge aufgerufen. Das zweite Feld des Attributs (Identifier) wird mit keinem bestimmten Wert initialisiert, es enthält 0.

Positionale und benannte Parameter

Um Identifier einen individuellen Wert zuzuweisen, lässt sich DeveloperAttribute auch wie folgt mit der Klasse verknüpfen:

[DeveloperAttribute("Meier", Identifier = 8815)] 
public class Demo
{
[...]
}

Listing 10.45 Verwendung positionaler und benannter Parameter

Beachten Sie, dass wir jetzt zwei Argumente übergeben, obwohl der Konstruktor nur einen Parameter definiert. Dies ist ein besonderes Merkmal der Attribute, denn beim Initialisieren eines Attributs können Sie sowohl positionale als auch benannte Parameter verwenden.

  • Positionale Parameter sind die Parameter für den Konstruktoraufruf und müssen immer angegeben werden, wenn das Attribut gesetzt wird.
  • Benannte Parameter sind optionale Parameter. In unserem Beispiel ist Name ein positionaler Parameter, dem die Zeichenfolge »Meier« übergeben wird, während Identifier ein benannter Parameter ist.

Benannte Parameter sind sehr flexibel. Einerseits können sie Standardwerte aufweisen, die grundsätzlich immer gültig sind, andererseits kann der Wert im Bedarfsfall individuell festgelegt werden.

Die Möglichkeit, benannte Parameter vorzusehen, befreit Sie von der Verpflichtung, für jede denkbare Kombination von Feldern und Eigenschaften überladene Konstruktoren in der Attributdefinition vorsehen zu müssen. Andererseits wird Ihnen damit aber nicht die Alternative entzogen, dennoch den Konstruktor zu überladen. Da unterscheiden sich die herkömmlichen Klassendefinitionen nicht von denen der Attribute.

Verknüpfen Sie ein Attribut mit einem Element und verwenden dabei positionale und benannte Parameter, müssen Sie eine wichtige Regel beachten: Zuerst werden die positionalen Parameter aufgeführt, danach die benannten. Die Reihenfolge der benannten Parameter ist beliebig, da der Compiler aufgrund der Parameternamen die angegebenen Werte richtig zuordnen kann. Benannte Parameter können alle öffentlich deklarierten Felder oder Eigenschaften sein – vorausgesetzt, sie sind weder statisch noch konstant definiert.


Rheinwerk Computing - Zum Seitenanfang

10.8.3 Attribute auswertenZur nächsten ÜberschriftZur vorigen Überschrift

Operationen, die auf die Existenz eines Attributs angewiesen sind, müssen zuerst feststellen, ob das erforderliche Attribut gesetzt ist oder nicht. Im folgenden Beispielprogramm soll dies für das Beispiel unseres eben entwickelten DeveloperAttribute gezeigt werden. Beachten Sie hier bitte, dass der Namespace System.Reflection bekannt gegeben werden muss.

// Beispiel: ..\Kapitel 10\AttributeSample
using System.Reflection;
[Developer("Meier")]
class Demo
{
[Developer("Fischer", Identifier=455)]
public void DoSomething() { }
public void DoMore() { }
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DeveloperAttribute : Attribute
{
public string Name { get; set; }
public int Identifier { get; set; }
public DeveloperAttribute(string name) {
Name = name;
}
}
class Program {
static void Main(string[] args) {
Type tDemo = typeof(Demo);
Type tAttr = typeof(DeveloperAttribute);
MethodInfo mInfo1 = tDemo.GetMethod("DoSomething");
MethodInfo mInfo2 = tDemo.GetMethod("DoMore");
// Prüfen, ob das Attribut bei der Klasse 'Demo' gesetzt ist
DeveloperAttribute attr =
(DeveloperAttribute)Attribute.GetCustomAttribute(tDemo, tAttr);
if (attr != null) {
Console.WriteLine("Name: {0}", attr.Name);
Console.WriteLine("Identifier: {0}", attr.Identifier);
}
else
Console.WriteLine("Attribut nicht gesetzt");
// Prüfen, ob das Attribut bei der Methode 'DoSomething' gesetzt ist
attr = (DeveloperAttribute)Attribute.GetCustomAttribute(mInfo1, tAttr);
if (attr != null) {
Console.WriteLine("Name: {0}", attr.Name);
Console.WriteLine("Identifier: {0}", attr.Identifier);
}
// Prüfen, ob das Attribut bei der Methode 'DoMore' gesetzt ist
bool isDefinied = Attribute.IsDefined(mInfo2, tAttr);
if (isDefinied)
Console.WriteLine("DoMore hat das Attribut.");
else
Console.WriteLine("DoMore hat das Attribut nicht.");
Console.ReadLine();
}
}

Listing 10.46 Beispielprogramm zur Auswertung eines Attributs

Das benutzerdefinierte Attribut DeveloperAttribute ist identisch mit demjenigen, das wir bereits vorher in diesem Abschnitt behandelt haben. Es erlaubt, mit einer Klasse oder einer Methode verknüpft zu werden. Die Klasse Demo, die dieses Attribut aufweist, enthält mit DoSomething und DoMore zwei Methoden, von denen nur die erstgenannte mit dem Attribut verknüpft ist.

Zur Beantwortung der Frage, ob ein bestimmtes Element mit dem DeveloperAttribute verknüpft ist oder nicht, greifen wir auf die Möglichkeiten einer Technik zurück, die als Reflection bezeichnet wird. Die Reflection gestattet es, die Metadaten einer .NET Assembly und der darin enthaltenen Datentypen zu untersuchen und auszuwerten. Zur Abfrage von Attributen stellt die Reflection die Klasse Attribute mit der statischen Methode GetCustomAttribute bereit. Da wir sowohl die Klasse als auch die Methoden untersuchen wollen, müssen wir auf zwei verschiedene Überladungen zurückgreifen. Für die Klasse ist es die folgende:

public static Attribute GetCustomAttribute(Module, Type);

Um eine Methode zu untersuchen, ist es die folgende Überladung:

public static Attribute GetCustomAttribute(MemberInfo, Type);

Im ersten Argument geben wir den Typ des zu untersuchenden Elements an, im zweiten Parameter den Typ des Attributs. Zur Beschreibung des Typs mittels Code wird von der Reflection die Klasse Type bereitgestellt. Diese beschreibt den Datentyp und kann auf zweierlei Art und Weise erzeugt werden:

  • unter Verwendung des Operators typeof, dem der Typbezeichner übergeben wird (z. B. typeof(Demo))
  • unter Aufruf der Methode GetType() auf eine Objektreferenz (z. B. myObject.GetType())

Um die Attribute einer Klasse auszuwerten, übergeben Sie der Methode GetCustomAttribute nur den Typ der Klasse und den Type des gesuchten Attributs. Zur Auswertung einer Methode ist ein MemberInfo-Objekt erforderlich. MemberInfo ist eine abstrakte Klasse im Namespace System.Reflection. Wir erhalten die Metadaten der zu untersuchenden Methode, wenn wir die Methode GetMethod des Type-Objects unter Angabe des Methodenbezeichners aufrufen. Der Typ der Rückgabe ist MethodInfo, eine von MemberInfo abgeleitete Klasse.

Der Typ der Rückgabe der beiden Überladungen von GetCustomAttribute ist Attribute. Dabei handelt es sich entweder um die Referenz auf das gefundene Attribut oder null, falls das Attribut nicht mit dem im ersten Parameter angeführten Element verknüpft ist. Daher erfolgt zuerst eine Konvertierung in das Zielattribut und anschließend eine Überprüfung, ob der Rückgabewert null ist.

DeveloperAttribute attr = (DeveloperAttribute)Attribute.GetCustomAttribute(tDemo, tAttr);
if (attr != null) {
Console.WriteLine("Name: {0}", attr.Name);
Console.WriteLine("Identifier: {0}", attr.Identifier;
}
else
Console.WriteLine("Attribut nicht gesetzt");

Listing 10.47 Auswertung, ob ein Attribut gesetzt ist

Da wir bei der Implementierung von Main wissen, dass nur unser benutzerdefiniertes Attribut DeveloperAttribute gesetzt ist (oder auch nicht), genügt uns diese Untersuchung. Ein Element kann natürlich auch mit mehreren Attributen verknüpft sein. Im Code müssten wir dann die Elemente auf alle gesetzten Attribute abfragen.


Rheinwerk Computing - Zum Seitenanfang

10.8.4 Festlegen der Assembly-Eigenschaften in »Assembly-Info.cs«Zur vorigen Überschrift

Jedes .NET-Projekt weist neben den Quellcodedateien auch die Datei AssemblyInfo.cs auf, die Metadaten über die Assemblierung beschreibt. Ganz allgemein dient diese Datei dazu, Zusatzinformationen zu der aktuellen Assemblierung bereitzustellen, beispielsweise eine Beschreibung, Versionsinformationen, Firmenname, Produktname und mehr. Diese werden im Windows Explorer in den Dateieigenschaften angezeigt. Da die Informationen die Assemblierung als Ganzes betreffen, müssen die Deklarationen außerhalb einer Klasse stehen und dürfen auch nur einmal gesetzt werden.

[assembly: AssemblyTitle("AssemblyTitle")]
[assembly: AssemblyDescription("AssemblyDescription")]
[assembly: AssemblyConfiguration("AssemblyConfiguration")]
[assembly: AssemblyCompany("Tollsoft")]
[assembly: AssemblyProduct("AssemblyProduct")]
[assembly: AssemblyCopyright("Copyright ©Tollsoft 2008")]
[assembly: AssemblyTrademark("AssemblyTrademark")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("948efa6b-af3a-4ba2-8835-b54b058015d4")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")

Listing 10.48 Die Datei »AssemblyInfo.cs«

Sie können die gewünschten Assembly-Informationen in der Datei AssemblyInfo.cs eintragen, Sie können aber auch die Einträge im Eigenschaftsdialog des Projekts vornehmen. Dazu öffnen Sie das Eigenschaftsfenster des Projekts und wählen die Lasche Anwendung. Auf dieser Registerkarte sehen Sie die Schaltfläche Assembly-Information..., über die der in Abbildung 10.2 gezeigte Dialog geöffnet wird.

Abbildung

Abbildung 10.2 Eintragen der Assembly-Informationen in Visual Studio 2012



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual C# 2012

Visual C# 2012
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: C/C++






 C/C++


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern