Skip to content

Instantly share code, notes, and snippets.

@jugemjugem
Created March 3, 2015 16:36
Show Gist options
  • Save jugemjugem/cabd86a54de0f47c38a8 to your computer and use it in GitHub Desktop.
Save jugemjugem/cabd86a54de0f47c38a8 to your computer and use it in GitHub Desktop.
attribute で代入の手抜き
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace AttrTest
{
class Program
{
static void Main(string[] args)
{
var a = new MyDomainObject();
// 適当なイベントデータを作成して。
var b = new MyEvent1Class {Name = "abcdefg"};
var c = new MyEvent2Class {Value = 1024, Value2 = 0.34f};
// 適当にデータを放り込む。
a.UpdateData(b);
a.UpdateData(c);
// 今度は適当に値を読み込んでみる。
var d = new MyEvent3Class();
a.FamilyName = "ハローワールド";
a.ReadData(d);
Console.WriteLine("Read d {0}", d.Family);
}
}
[AttributeUsage(AttributeTargets.Class)]
class EventInfoAttribute : System.Attribute
{
/// <summary>
/// イベントID
/// </summary>
public int EventId { get; set; }
}
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
class EventListenerAttribute : Attribute
{
/// <summary>
/// 監視対象のイベントID
/// </summary>
public int EventId { get; set; }
/// <summary>
/// Get/Setするプロパティの名前
/// </summary>
public string PropetyName { get; set; }
}
[EventInfoAttribute(EventId = 100)]
class MyEvent1Class
{
public string Name { get; set; }
}
[EventInfoAttribute(EventId = 200)]
class MyEvent2Class
{
public int Value { get; set; }
public float Value2 { get; set; }
}
[EventInfoAttribute(EventId = 400)]
class MyEvent3Class
{
public string Family { get; set; }
}
class MyDomainObject
{
private static readonly Dictionary<int, List< Tuple< PropertyInfo, string> > > ThisPropertyInfos
= new Dictionary<int, List<Tuple<PropertyInfo, string>>>();
static MyDomainObject()
{
var propertyInfos = typeof(MyDomainObject).GetProperties();
foreach (var propertyInfo in propertyInfos)
{
var listeners = propertyInfo.GetCustomAttributes<EventListenerAttribute>();
foreach (var listener in listeners)
{
if (ThisPropertyInfos.ContainsKey(listener.EventId))
{
ThisPropertyInfos[listener.EventId].Add(Tuple.Create(propertyInfo, listener.PropetyName));
}
else
{
ThisPropertyInfos[listener.EventId] = new List<Tuple<PropertyInfo, string>>
{
Tuple.Create(propertyInfo, listener.PropetyName)
};
}
}
}
}
/// <summary>
/// arg の属性に従って、値をセットする関数
/// </summary>
/// <param name="arg">値をセットしたい EventInfoAttribute 属性付きデータ</param>
public void UpdateData(object arg)
{
var list = arg.GetType()
.GetCustomAttributes<EventInfoAttribute>(true);
foreach (var item in list)
{
Console.WriteLine("{0}, {1}", item.EventId, item.ToString());
#if true
List<Tuple<PropertyInfo, string>> targets;
if (ThisPropertyInfos.TryGetValue(item.EventId, out targets))
{
foreach (var propertyInfo in targets)
{
var argType = arg.GetType().GetProperty(propertyInfo.Item2);
if (propertyInfo.Item1.PropertyType == argType.PropertyType)
{
propertyInfo.Item1.SetValue(this, argType.GetValue(arg));
}
}
}
#else
var props = this.GetType().GetProperties();
foreach (var propItem in props)
{
var listeners = propItem.GetCustomAttributes<EventListenerAttribute>();
foreach (var listener in listeners)
{
if (listener.EventId == item.EventId)
{
if (propItem.PropertyType == arg.GetType().GetProperty(listener.PropetyName).PropertyType)
{
propItem.SetValue(this, arg.GetType().GetProperty(listener.PropetyName).GetValue(arg));
Console.WriteLine("{0}, {1}", listener.EventId, listener.ToString());
}
}
}
}
#endif
}
}
/// <summary>
/// arg の属性に従って、値を読み取る。
/// </summary>
/// <param name="arg">値を読み込みたい EventInfoAttribute 属性付きデータ</param>
public void ReadData(object arg)
{
var list = arg.GetType()
.GetCustomAttributes<EventInfoAttribute>(true);
foreach (var item in list)
{
List<Tuple<PropertyInfo, string>> targets;
if (ThisPropertyInfos.TryGetValue(item.EventId, out targets))
{
foreach (var propertyInfo in targets)
{
var argType = arg.GetType().GetProperty(propertyInfo.Item2);
if (propertyInfo.Item1.PropertyType == argType.PropertyType)
{
argType.SetValue(arg,
propertyInfo.Item1.GetValue(this)
);
}
}
}
}
}
/// <summary>
/// 楽をしたい属性1
/// </summary>
[EventListenerAttribute(EventId = 100, PropetyName = "Name")]
public string ObjectName { get; set; }
/// <summary>
/// 楽をしたい属性2
/// </summary>
[EventListenerAttribute(EventId = 200, PropetyName = "Value")]
public int ArgValue { get; set; }
/// <summary>
/// 楽をしたい属性3、同じ番号。
/// </summary>
[EventListenerAttribute(EventId = 200, PropetyName = "Value2")]
public float ArgValue2 { get; set; }
/// <summary>
/// 楽をしたい属性4、いろんなイベントを受付。
/// </summary>
[EventListenerAttribute(EventId = 100, PropetyName = "Name")]
[EventListenerAttribute(EventId = 400, PropetyName = "Family")]
public string FamilyName { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment