2014-10-29 142 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的字符串值。