此法底層仍是透過 call Property/Method 方式取得/設定實際資料, 但其加入中間層(封裝)方式進行呼叫, 好處是當 原始 Class Property/Method 變動名稱時, 原始用到的程式可以不用跟著調整
► Class
► Class
public class TestModel
{
public TestModel(int id, string c1)
{
this.id = id;
this.c1 = c1;
}
[CodeName("A1")]
public int id { get; set; }
[CodeName("A2")]
public string c1 { get; set; }
[CodeName("A3")]
public DateTime? c2 { get; set; }
//
public int getId() {
return id;
}
public class CodeNameAttribute : Attribute
{
private readonly string name;
public CodeNameAttribute(string name) { this.name = name; }
public string Name { get { return name; } }
}
public static TOutput Call<TOutput>(object callByAttribute, string name, object[] args)
{
PropertyInfo prop = callByAttribute.GetType().GetProperties()
.Where(p => p.IsDefined(typeof(CodeNameAttribute), false))
.SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name);
if (prop != null)
return (TOutput)callByAttribute.GetType().InvokeMember(prop.Name, BindingFlags.GetProperty, null, callByAttribute, null);
MethodInfo method = callByAttribute.GetType().GetMethods()
.Where(p => p.IsDefined(typeof(CodeNameAttribute), false))
.SingleOrDefault(p => ((CodeNameAttribute)(p.GetCustomAttributes(typeof(CodeNameAttribute), false)).First()).Name == name);
if (method != null)
return (TOutput)callByAttribute.GetType().InvokeMember(method.Name, BindingFlags.InvokeMethod, null, callByAttribute, args);
throw new Exception("method/getter not found");
}
public static TOutput Call<TOutput>(object callByAttribute, string name)
{
return Call<TOutput>(callByAttribute, name, null);
}
}
► Call Attribute
Console.WriteLine("CallByAttribute=" + TestModel.Call<String>(i, "A2"));
from http://stackoverflow.com/questions/3706037/calling-a-property-or-method-...