<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>experimentalworks &#187; C#</title>
	<atom:link href="http://blog.experimentalworks.net/category/programming/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.experimentalworks.net</link>
	<description></description>
	<lastBuildDate>Wed, 14 Jul 2010 15:35:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>.NET Attribute und Reflection</title>
		<link>http://blog.experimentalworks.net/2006/09/net-attribute-und-reflection/</link>
		<comments>http://blog.experimentalworks.net/2006/09/net-attribute-und-reflection/#comments</comments>
		<pubDate>Sun, 03 Sep 2006 15:52:43 +0000</pubDate>
		<dc:creator>dsp</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://wp.experimentalworks.net/?p=14</guid>
		<description><![CDATA[.NET bietet einen Mechanismus an Assembly-, Klassen-, M [...]]]></description>
			<content:encoded><![CDATA[<p>.NET bietet einen Mechanismus an Assembly-, Klassen-, Methoden-, Felder- oder Propertiesdefinitionen Metadaten anzuhängen &#8211; sogenannten Attribute.<br />
Wir sehen uns nun an, wie man eigene Attribute definiert und sie mittel Reflection wieder ausliest.<span id="more-14"></span><br />
<h3>Attribut Deklaration</h3>
<p>Ein Attribute, dass an eine Methode gebunden ist:</p>
<blockquote><p>
 class Test<br />
 {<br />
     [MyAttribute]<br />
     public void helloWorld ()<br />
     {<br />
     }<br />
}
</p></blockquote>
<h3>Custom-Attribute</h3>
<p>Eigene Attribute werden immer als Unterklasse von &#8221;&#8217;System.Attribute&#8221;&#8217; deklariert. Zusätzlich wird über Attribute (sogennante Meta-Attribute) festgelegt in welchem Kontext das Attribute erlaubt ist. Attributklassen müssen &#8221;&#8217;public&#8221;&#8217; sein.</p>
<h3>Die Klasse CodeInfoAttribute</h3>
<p>Wir wollen nun ein selbstdefiniertes Attribut &#8221;&#8217;CodeInfo&#8221;&#8217; erstellen, dass Informationen wie Author oder Editierungsdatum enthält.</p>
<blockquote><p>
 namespace Net.Experimentalworks.Attributes<br />
 {<br />
   [AttributeUsage(AttributeTargets.Class |<br />
                             AttributeTargets.Method |<br />
                             AttributeTargets.Struct,<br />
                             Inherited = false,<br />
                             AllowMultiple = true)]<br />
   class CodeInfoAttribute : System.Attribute<br />
   {<br />
   }<br />
 }
</p></blockquote>
<p>Die Namensgebung ist ein vom Compiler unterstützt Übereinkunft, dass alle Attribute mit <em>*Attribute</em> enden. Man kann spÃƒÂ¤ter sowohl mit <b>[CodeInfoAttribute]</b> als auch mit <b>[CodeInfo]</b> auf das Attribut zugreifen.</p>
<h3>AttributUsage</h3>
<p>Das Meta-Attribut <b>AttributeUsage</b> gibt an, in welchem Kontext das Attribut gültigt ist.<br />
<b>AttributeTarget</b><br />
Möglichkeiten:</p>
<ul>
<li>AttributeTarget.All</li>
<li>AttributeTarget.Assembly</li>
<li>AttributeTarget.Class</li>
<li>AttributeTarget.Constructor</li>
<li>AttributeTarget.Delegate</li>
<li>AttributeTarget.Enum</li>
<li>AttributeTarget.Event</li>
<li>AttributeTarget.Field</li>
<li>AttributeTarget.Interface</li>
<li>AttributeTarget.Method</li>
<li>AttributeTarget.Module</li>
<li>AttributeTarget.Parameter</li>
<li>AttributeTarget.Property</li>
<li>AttributeTarget.ReturnValue</li>
<li>AttributeTarget.Struct</li>
</ul>
<p><b>Inherited</b><br />
Gibt an, ob ein in einer Basisklasse verwendetes Attribut auf die Unterklassen vererbt wird.<br />
<b>AllowMultiple</b><br />
Der Boolean-Parameter AllowMultiple gibt an, ob ein Attribut mehrfach im selbsten Kontext vorkommen darf.<br />
<b>Beispiel</b></p>
<blockquote><p>
[AttributeUsage(AttributeTarget.All,Inherited=true,AllowMultiple=true)]
</p></blockquote>
<h3> Parametisierung von Custom-Attributen </h3>
<p>Jedes Attribut kann zusätzliche Parameter beim Aufruf erhalten. Man unterscheidet zwischen <b>Named-Parameters</b> und <b>Position-Parameters</b>.</p>
<p><b>Position-Parameters</b><br />
Position-Parametisierung ähnelt dem Aufruf eines Konstruktors und wird über diesen implementiert.</p>
<blockquote><p>
 [CodeInfo("AuthorName")]<br />
 public void hello()<br />
 {<br />
 }
</p></blockquote>
<p><b>Die Erweiterung der Klasse CodeInfo</b><br />
Um die Beschreibung, die bei der Verwendung des Attributes angegeben werden kann zu unterstützen können,<br />
benötigen wir einen Konstruktor, der den Description-Parameter übernimmt. </p>
<blockquote><p>
 namespace Net.Experimentalworks.Attributes<br />
 {<br />
   [AttributeUsage(AttributeTargets.Class |<br />
                             AttributeTargets.Method |<br />
                             AttributeTargets.Struct,<br />
                             Inherited = false,<br />
                             AllowMultiple = true)]<br />
   class CodeInfoAttribute : System.Attribute<br />
   {<br />
      private string author;<br />
      private string date;<br />
      // Wir unterstüzen weiterhin eine parameterlose Initialisierung<br />
      public CodeInfoAttribute(string Author)<br />
      {<br />
         author = Author;<br />
      }</p>
<p>      public CodeInfoAttribute(string Author, string Date) : this(Author)<br />
      {<br />
         date = Date;<br />
      }<br />
   }<br />
 }
</p></blockquote>
<p>Unser Attribut kann also mit oder ohne Parameter initialisiert werden:</p>
<blockquote><p>
 [CodeInfo("dsp")]<br />
 [CodeInfo("dsp", "03.09.2006")]
</p></blockquote>
<p><b> Named-Parameters</b></p>
<blockquote><p>
 [CodeInfo(Date="03.09.2006", Author="dsp")]
</p></blockquote>
<p><b>Die Erweiterung der Klasse ConfiguratableAttribute</b><br />
Named-Parameters werden über Properties bzw. Fields implementiert. Für jeden Namend-Parameter muss eine öffentlich lesbare Poperty oder ein Feld mit demselben Namen existieren.</p>
<blockquote><p>
 namespace Net.Experimentalworks.Attributes<br />
 {<br />
   [AttributeUsage(AttributeTargets.Class |<br />
                             AttributeTargets.Method |<br />
                             AttributeTargets.Struct,<br />
                             Inherited = false,<br />
                             AllowMultiple = true)]<br />
   class CodeInfoAttribute : System.Attribute<br />
   {<br />
      // Als Feld:<br />
      public string Author;</p>
<p>      // Als Poperty:<br />
      private DateTime date;<br />
      public string Date<br />
      {<br />
         get {<br />
              return date.ToString();<br />
         }<br />
         set {<br />
              date = DateTime.Parse(value);<br />
         }<br />
      }<br />
   }<br />
 }
 </p></blockquote>
<h3>Mischformen</h3>
<p>Natürlich sind auch Mischformen möglich.</p>
<blockquote><p>
 using System;<br />
 namespace Net.Experimentalworks.Attributes<br />
 {<br />
   [AttributeUsage(AttributeTargets.Class |<br />
                             AttributeTargets.Method |<br />
                             AttributeTargets.Struct,<br />
                             Inherited = false,<br />
                             AllowMultiple = true)]<br />
   class CodeInfoAttribute : System.Attribute<br />
   {<br />
        public string Author;<br />
        public string Date;<br />
        public CodeInfoAttribute(string author)<br />
        {<br />
           Author = author;<br />
        }</p>
<p>        public CodeInfoAttribute(string author, string date) : this(author)<br />
        {<br />
           Date = date;<br />
        }<br />
    }<br />
 }
</p></blockquote>
<h3> Zugriff über Reflection</h3>
<p>Das Attribut lässt sich über Reflection von .NET auslesen. Reflection ist ein Mechanismus der es erlaubt während der Laufzeit auf Klassendeklarationen und Metadaten zuzugreifen.<br />
<b>Beispiel</b></p>
<blockquote><p>
 using System;<br />
 using System.Reflection;<br />
 namespace Net.Experimentalworks.Attributes.Inspection<br />
 {<br />
  public class Inspector<br />
  {<br />
   public void printAllCodeInfoMethods (string ClassName)<br />
   {<br />
      foreach(MemberInfo mi in Type.GetType(ClassName).GetMembers())<br />
      {<br />
            foreach (Object att in ((MemberInfo) mi).GetCustomAttributes(true))<br />
            {<br />
                   if (att.GetType().Name == &#8220;CodeInfoAttribute&#8221;)<br />
                   {<br />
                           Console.WriteLine(&#8220;Type: {0} Name: {1} Author: {2}&#8221;,<br />
                                             mi.MemberType, mi.Name, ((CodeInfoAttribute)att).Date);<br />
                   }<br />
            }<br />
       }<br />
   }<br />
 }
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.experimentalworks.net/2006/09/net-attribute-und-reflection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
