2014-10-29 106 views
1

我有一個類,我想回到我可以定義爲像這樣的屬性基於字符串的各種屬性的值:字典映射字符串性能

[FieldName("data_bus")] 
    public string Databus 
    { 
     get { return _record.Databus; } 
    } 

所以像我的字典控股:

private static readonly IDictionary<string, Func<string>> PropertyMap; 

這是這裏初始化:

static MyClass() 
    { 
     PropertyMap = new Dictionary<string, Func<string>>(); 

     var myType = typeof(ArisingViewModel); 

     foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) 
     { 
      if (propertyInfo.GetGetMethod() != null) 
      { 
       var attr = propertyInfo.GetCustomAttribute<FieldNameAttribute>(); 

       if (attr == null) 
        continue; 

       PropertyInfo info = propertyInfo; 
       PropertyMap.Add(attr.FieldName,() => info.Name); 
       // Not sure what I'm doing here. 
      } 
     } 
    } 

不知怎麼調用阿龍g行:

public static object GetPropertyValue(object obj, string field) 
    { 

     Func<string> prop; 
     PropertyMap.TryGetValue(field, out prop); 
     // return 
    } 

任何人都可以告訴我如何設置它?我不確定我是否正確理解Func的工作原理。

回答

3

你需要改變你的字典中的定義,以便該函數將接受類

private static readonly IDictionary<string, Func<ArisingViewModel,string>> PropertyMap; 

然後你需要的一個實例,你的靜態初始化是

static MyClass() 
{ 
    PropertyMap = new Dictionary<string, Func<ArisingViewModel,string>>(); 

    var myType = typeof(ArisingViewModel); 

    foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) 
    { 
     if (propertyInfo.GetGetMethod() != null) 
     { 
      var attr = propertyInfo.GetCustomAttribute<FieldNameAttribute>(); 

      if (attr == null) 
       continue; 

      PropertyInfo info = propertyInfo; 
      PropertyMap.Add(attr.FieldName, obj => (string)info.GetValue(obj,null)); 
     } 
    } 
} 

public static object GetPropertyValue(ArisingViewModel obj, string field) 
{ 
    Func<ArisingViewModel,string> prop; 
    if (PropertyMap.TryGetValue(field, out prop)) { 
     return prop(obj); 
    } 
    return null; //Return null if no match 
    } 

您也可以讓你的如果你願意的話,解決方案更通用一些。

public static MyClass<T> { 

    private static readonly IDictionary<string, Func<T,string>> PropertyMap; 


    static MyClass() 
    { 
    PropertyMap = new Dictionary<string, Func<T,string>>(); 

    var myType = typeof(T); 

    foreach (var propertyInfo in myType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) 
    { 
     if (propertyInfo.GetGetMethod() != null) 
     { 
      var attr = propertyInfo.GetCustomAttribute<FieldNameAttribute>(); 

      if (attr == null) 
       continue; 

      PropertyInfo info = propertyInfo; 
      PropertyMap.Add(attr.FieldName, obj => (string)info.GetValue(obj,null)); 
     } 
    } 
    } 

    public static object GetPropertyValue(T obj, string field) 
    { 
    Func<ArisingViewModel,string> prop; 
    if (PropertyMap.TryGetValue(field, out prop)) { 
     return prop(obj); 
    } 
    return null; //Return null if no match 
    } 
} 

編輯 - 並調用通用版本,你會做

var value = MyClass<ArisingViewModel>.GetPropertyValue(mymodel,"data_bus"); 
+0

謝謝,這是一個絕對完美的答案。 – jimbo 2014-10-29 11:26:31

0

你是在正確的軌道上。請參閱下面的例子,與您擁有的相似。

Dictionary<string, Func<string>> dic = new Dictionary<string, Func<string>>(); 
private void test() 
{ 
    Button btn = new Button(); 
    btn.Text = "BlahBlah"; 
    dic.Add("Value",() => btn.Text); 
} 

private void test2() 
{ 
    Func<string> outval; 
    dic.TryGetValue("Value", out outval); 
    MessageBox.Show(outval()); 
} 

在示例test()中,我定義了一個新的Button類併爲其.Text屬性賦值。然後我在我的詞典<>中添加一個新條目。在test2()中,我檢索該Func並調用它,它返回btn.Text的字符串值。