Dictionary mapping strings to properties

后端 未结 2 494
粉色の甜心
粉色の甜心 2020-12-21 13:14

I have a class where I would like to return the value of various properties based on a string that I can define as an attribute like so:

    [FieldName(\"dat         


        
相关标签:
2条回答
  • 2020-12-21 13:33

    You are on the right track. See below with an example similar to what you have.

    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());
    }
    

    In the example test(), I define a new Button class and assign a value to its .Text property. Then I add a new entry into my Dictionary<>. In test2() I retrieve that Func and invoke it, which returns the string value of btn.Text.

    0 讨论(0)
  • 2020-12-21 13:35

    you will need to change your dictionary definition so that the function will accept an instance of the class

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

    Then you need your static initializer to be

    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
      }
    

    You can also make your solution a little more generic if you wish.

    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
      }
    }
    

    EDIT -- and to call the generic version you would do

    var value = MyClass<ArisingViewModel>.GetPropertyValue(mymodel,"data_bus");
    
    0 讨论(0)
提交回复
热议问题