Sunday, February 3, 2013

C# attributes used to seem mysterious to me, but actually they are kind of underwhelming.

Here is more magic from C# 4.0 in a Nutshell, the book I have been nibbling on for a forever. Look at the last of the three tests here for how to get data back from an attribute as this shows off how to use attributes.

using System;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using RockPaperScissors.Models;
namespace RockPaperScissors.Tests
{
   [TestClass]
   public class AttributesTest
   {
      [TestMethod]
      public void defeated_value_should_start_as_false_for_all_types_of_hands()
      {
         
//arrange
         Rock rock = new Rock();
         Paper paper = new Paper();
         Scissors scissors = new Scissors();
         
         
//assert
         Assert.IsFalse(rock.IsDefeated);
         Assert.IsFalse(paper.IsDefeated);
         Assert.IsFalse(scissors.IsDefeated);
      }
      
      [TestMethod]
      public void defeat_methods_behave_as_expected_for_all_types_of_hands()
      {
         
//arrange
         Rock rock = new Rock();
         Paper paper = new Paper();
         Scissors scissors = new Scissors();
         
         
//act
         rock = paper.WrapRock(rock);
         paper = scissors.CutPaper(paper);
         scissors = rock.CrushScissors(scissors);
         
         
//assert
         Assert.IsTrue(rock.IsDefeated);
         Assert.IsTrue(paper.IsDefeated);
         Assert.IsTrue(scissors.IsDefeated);
      }
      
      [TestMethod]
      public void attributes_behave_as_expected_for_all_types_of_hands()
      {
         
//arrange
         Type rock = typeof (Rock);
         MethodInfo rockMethod = rock.GetMethods()[0];
         Type paper = typeof (Paper);
         MethodInfo paperMethod = paper.GetMethods()[0];
         Type scissors = typeof (Scissors);
         MethodInfo scissorsMethod = scissors.GetMethods()[0];
         
         
//act
         NoteAttribute rockMethodNote = (NoteAttribute)
               Attribute.GetCustomAttribute(rockMethod, typeof (NoteAttribute));
         NoteAttribute paperMethodNote = (NoteAttribute)
               Attribute.GetCustomAttribute(paperMethod, typeof (NoteAttribute));
         NoteAttribute scissorsMethodNote = (NoteAttribute)
               Attribute.GetCustomAttribute(scissorsMethod, typeof(NoteAttribute));
         
         
//assert
         Assert.AreEqual(rockMethodNote.Note, "Rock crushes scissors.");
         Assert.AreEqual(paperMethodNote.Note, "Paper wraps rock.");
         Assert.AreEqual(scissorsMethodNote.Note, "Scissors cut paper.");
      }
   }
}

 
 

Alright, I will show you the attribute class itself, but first, please take in these four classes:

  1. using System;
    namespace RockPaperScissors.Models
    {
       public abstract class Hand
       {
          public Boolean IsDefeated { get; set; }
          public Hand()
          {
             IsDefeated = false;
          }
       }
    }
     
  2. namespace RockPaperScissors.Models
    {
       public class Rock : Hand
       {
          [Note("Rock crushes scissors.")]
          public Scissors CrushScissors(Scissors scissors)
          {
             scissors.IsDefeated = true;
             return scissors;
          }
       }
    }
     
  3. namespace RockPaperScissors.Models
    {
       public class Paper : Hand
       {
          [Note("Paper wraps rock.")]
          public Rock WrapRock(Rock rock)
          {
             rock.IsDefeated = true;
             return rock;
          }
       }
    }
     
  4. namespace RockPaperScissors.Models
    {
       public class Scissors : Hand
       {
          [Note("Scissors cut paper.")]
          public Paper CutPaper(Paper paper)
          {
             paper.IsDefeated = true;
             return paper;
          }
       }
    }

 
 

In conclusion, here is the attribute class itself:

using System;
namespace RockPaperScissors.Models
{
   [AttributeUsage (AttributeTargets.Method)]
   public class NoteAttribute : Attribute
   {
      public string Note { get; private set; }
      public NoteAttribute(string note)
      {
         Note = note;
      }
   }
}

No comments:

Post a Comment