Skip to content

Instantly share code, notes, and snippets.

@myaumyau
Created February 15, 2013 08:30
Show Gist options
  • Save myaumyau/4959137 to your computer and use it in GitHub Desktop.
Save myaumyau/4959137 to your computer and use it in GitHub Desktop.
[C#]EnumExtentionAttribute
// http://blog.masa1115.com/?p=1062
using System;
using System.Collections.Generic;
using System.Reflection;
namespace XXX.Izu.Library.Utility.Enum
{
/// <summary>;
/// Enum拡張属性ベースクラス
/// </summary>;
/// <remarks>;
/// Enumが表す様々な情報をEnumとともに保持するための属性クラス
/// </remarks>;
[AttributeUsage ( AttributeTargets.Field, AllowMultiple = false, Inherited = true )]
public abstract class EnumExtentionAttribute : Attribute
{
#region " Private Field "
/// <summary>;
/// 拡張属性プロパティ保持用ディクショナリ
/// </summary>;
private readonly Dictionary<string, object="">; _informations;
#endregion
#region " Constructor "
/// <summary>;
/// コンストラクタ
/// </summary>;
/// <remarks>;
/// 派生クラスのコンストラクタから呼び出す。
/// 3項目以上をプロパティとして保持する場合に使用
/// </remarks>;
protected EnumExtentionAttribute ( )
{
_informations = new Dictionary<string, object="">; ( );
}
/// <summary>;
/// コンストラクタ
/// </summary>;
/// <remarks>;
/// 派生クラスのコンストラクタから呼び出す。
/// 単純なキー、値のペアを属性として保持する場合に使用
/// </remarks>;
/// <param name="informations">;
/// Enumに付随する属性を保持したディクショナリ
/// ;
protected EnumExtentionAttribute ( Dictionary<string, object="">; informations )
{
_informations = informations;
}
#endregion
#region " Indexer "
/// <summary>;
/// インデクサ
/// </summary>;
/// <remarks>;
/// Enumに付随する各種情報を取得するために使用
/// </remarks>;
/// <param name="key">;情報のキー/プロパティ名など;
public object this [ string key ]
{
get
{
try
{
return _informations [ key ];
}
catch ( KeyNotFoundException )
{
throw new PropertyNotExistsException ( GetType ( ), key );
}
}
protected set
{
if ( !_informations.ContainsKey ( key ) )
{
_informations.Add ( key, value );
return;
}
_informations [ key ] = value;
}
}
#endregion
#region " Static Member "
/// <summary>;
/// Enum値の情報を取得するためのメソッド
/// </summary>;
/// <param name="field">;対象となるEnum値;
/// <returns>;Enum値のフィールド情報</returns>;
private static FieldInfo GetFieldInfo ( System.Enum field )
{
var enumType = field.GetType ( );
var name = System.Enum.GetName ( enumType, field );
return enumType.GetField ( name );
}
/// <summary>;
/// Enum値に設定された拡張属性を取得するためのメソッド
/// </summary>;
/// <typeparam name="T">;拡張属性の型を指定</typeparam>;
/// <param name="field">;対象となるEnum値;
/// <returns>;拡張属性のインスタンス</returns>;
/// <exception cref="NotExtendedException">;指定したEnum値に拡張属性が設定されていない場合に発生</exception>;
protected static T GetAttribute<t>; ( System.Enum field ) where T : Attribute
{
var attr = ( T ) GetCustomAttribute ( GetFieldInfo ( field ), typeof ( T ) );
if ( attr == null )
throw new NotExtendedException ( typeof ( T ), field );
return attr;
}
#endregion
}
}
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using XXX.Izu.Library.Utility.Enum;
namespace TestProject.Utility
{
#region " Enum拡張属性のシンプルな使用例 "
#region " サンプルクラス "
/// <summary>;
/// Enum拡張属性サンプルクラス(シンプルな拡張:名前、値)
/// </summary>;
public class SimpleEnumExtentionAttribute : EnumExtentionAttribute
{
public SimpleEnumExtentionAttribute(string name, string value)
: base(new Dictionary<string, object="">;() { { name, value } })
{ }
public static SimpleEnumExtentionAttribute GetAttribute(System.Enum field)
{
return GetAttribute<simpleenumextentionattribute>;(field);
}
}
#endregion
#region " サンプルEnum "
public enum WeekDay1
{
[SimpleEnumExtention("Sunday", "日")]
Sunday = 0,
[SimpleEnumExtention("Monday", "月")]
Monday = 1,
[SimpleEnumExtention("Tuesday", "火")]
Tuesday = 2,
[SimpleEnumExtention("Wednesday", "水")]
Wednesday = 3,
[SimpleEnumExtention("Thursday", "木")]
Thursday = 4,
[SimpleEnumExtention("Friday", "金")]
Friday = 5,
[SimpleEnumExtention("Saturday", "土")]
Saturday = 6
}
#endregion
#endregion
#region " Enum拡張属性の使用例 "
#region " サンプルクラス "
/// <summary>;
/// Enum拡張属性サンプルクラス
/// </summary>;
public class Sample1EnumExtentionAttribute : EnumExtentionAttribute
{
public string Name
{
get { return base["Name"].ToString(); }
set { base["Name"] = value; }
}
public string ShortName
{
get { return base["ShortName"].ToString(); }
set { base["ShortName"] = value; }
}
public string Value
{
get { return base["Value"].ToString(); }
set { base["Value"] = value; }
}
public static Sample1EnumExtentionAttribute GetAttribute(System.Enum field)
{
return GetAttribute<sample1enumextentionattribute>;(field);
}
}
#endregion
#region " サンプルEnum "
public enum WeekDay2
{
[Sample1EnumExtention(Name = "Sunday", ShortName = "Sun", Value = "日")]
Sunday = 0,
[Sample1EnumExtention(Name = "Monday", ShortName = "Mon", Value = "月")]
Monday = 1,
[Sample1EnumExtention(Name = "Tuesday", ShortName = "Tue", Value = "火")]
Tuesday = 2,
[Sample1EnumExtention(Name = "Wednesday", ShortName = "Wed", Value = "水")]
Wednesday = 3,
[Sample1EnumExtention(Name = "Thursday", ShortName = "Thu", Value = "木")]
Thursday = 4,
[Sample1EnumExtention(Name = "Friday", ShortName = "Fri", Value = "金")]
Friday = 5,
[Sample1EnumExtention(Name = "Saturday", ShortName = "Sat", Value = "土")]
Saturday = 6,
NotExtend = 7
}
#region " サンプルEnum Extention"
static class WeekDay2Extension
{
public static string Name(this WeekDay2 self)
{
return Sample1EnumExtentionAttribute.GetAttribute(self).Name;
}
public static string ShortName(this WeekDay2 self)
{
return Sample1EnumExtentionAttribute.GetAttribute(self).ShortName;
}
public static string Value(this WeekDay2 self)
{
return Sample1EnumExtentionAttribute.GetAttribute(self).Value;
}
}
#endregion
#endregion
#endregion
/// <summary>;
/// UnitTest_EnumExtAttribute の概要の説明
/// </summary>;
[TestClass]
public class UnitTest_EnumExtAttribute
{
public UnitTest_EnumExtAttribute ( )
{
//
// TODO: コンストラクタ ロジックをここに追加します
//
}
private TestContext testContextInstance;
/// <summary>;
///現在のテストの実行についての情報および機能を
///提供するテスト コンテキストを取得または設定します。
///</summary>;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
#region 追加のテスト属性
//
// テストを作成する際には、次の追加属性を使用できます:
//
// クラス内で最初のテストを実行する前に、ClassInitialize を使用してコードを実行してください
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// クラス内のテストをすべて実行したら、ClassCleanup を使用してコードを実行してください
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// 各テストを実行する前に、TestInitialize を使用してコードを実行してください
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// 各テストを実行した後に、TestCleanup を使用してコードを実行してください
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
public void シンプル拡張属性のキー値アクセス_EQ ( )
{
Assert.AreEqual ( "日", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Sunday ) [ "Sunday" ] );
Assert.AreEqual ( "月", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Monday ) [ "Monday" ] );
Assert.AreEqual ( "火", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Tuesday ) [ "Tuesday" ] );
Assert.AreEqual ( "水", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Wednesday ) [ "Wednesday" ] );
Assert.AreEqual ( "木", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Thursday ) [ "Thursday" ] );
Assert.AreEqual ( "金", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Friday ) [ "Friday" ] );
Assert.AreEqual ( "土", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Saturday ) [ "Saturday" ] );
}
[TestMethod]
public void シンプル拡張属性のキー値アクセス_NotEQ ( )
{
Assert.AreNotEqual ( "月", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Sunday ) [ "Sunday" ] );
Assert.AreNotEqual ( "日", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Monday ) [ "Monday" ] );
}
[TestMethod]
[ExpectedException ( typeof ( PropertyNotExistsException ) )]
public void シンプル拡張属性のキー値アクセス_失敗1 ( )
{
Assert.AreNotEqual ( "日", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay1.Sunday ) [ "Invalid" ] );
}
[TestMethod]
[ExpectedException ( typeof ( NotExtendedException ) )]
public void シンプル拡張属性のキー値アクセス_失敗2 ( )
{
Assert.AreNotEqual ( "日", SimpleEnumExtentionAttribute.GetAttribute ( WeekDay2.NotExtend ) [ "Invalid" ] );
}
[TestMethod]
public void サンプル1拡張属性のプロパティアクセス_EQ ( )
{
Assert.AreEqual ( "Sunday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Sunday ).Name );
Assert.AreEqual ( "Monday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Monday ).Name );
Assert.AreEqual ( "Tuesday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Tuesday ).Name );
Assert.AreEqual ( "Wednesday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Wednesday ).Name );
Assert.AreEqual ( "Thursday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Thursday ).Name );
Assert.AreEqual ( "Friday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Friday ).Name );
Assert.AreEqual ( "Saturday", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Saturday ).Name );
Assert.AreEqual ( "Sun", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Sunday ).ShortName );
Assert.AreEqual ( "Mon", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Monday ).ShortName );
Assert.AreEqual ( "Tue", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Tuesday ).ShortName );
Assert.AreEqual ( "Wed", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Wednesday ).ShortName );
Assert.AreEqual ( "Thu", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Thursday ).ShortName );
Assert.AreEqual ( "Fri", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Friday ).ShortName );
Assert.AreEqual ( "Sat", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Saturday ).ShortName );
Assert.AreEqual ( "日", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Sunday ).Value );
Assert.AreEqual ( "月", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Monday ).Value );
Assert.AreEqual ( "火", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Tuesday ).Value );
Assert.AreEqual ( "水", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Wednesday ).Value );
Assert.AreEqual ( "木", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Thursday ).Value );
Assert.AreEqual ( "金", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Friday ).Value );
Assert.AreEqual ( "土", Sample1EnumExtentionAttribute.GetAttribute ( WeekDay2.Saturday ).Value );
}
[TestMethod]
public void サンプル1拡張属性のプロパティアクセス_拡張メソッド経由_EQ()
{
Assert.AreEqual("Sunday", WeekDay2.Sunday.Name());
Assert.AreEqual("Monday", WeekDay2.Monday.Name());
Assert.AreEqual("Tuesday", WeekDay2.Tuesday.Name());
Assert.AreEqual("Wednesday", WeekDay2.Wednesday.Name());
Assert.AreEqual("Thursday", WeekDay2.Thursday.Name());
Assert.AreEqual("Friday", WeekDay2.Friday.Name());
Assert.AreEqual("Saturday", WeekDay2.Saturday.Name());
Assert.AreEqual("Sun", WeekDay2.Sunday.ShortName());
Assert.AreEqual("日", WeekDay2.Sunday.Value());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment