2

这是我最近经常遇到的一个问题。我知道一种让它工作的技巧,但我不确定这是否是最好的方法,但它似乎是唯一没有反思的方法,这似乎是普遍不鼓励的。

我正在尝试做的事情:我有我希望能够通过用户输入(字符串)修改的类实例。因此,例如:

public class Apple
{

   private String color; //Color of the apple
   private float cost; //Cost of the apple
   private double radius; //Radius of the apple

   public Apple()
   {
      this.color = "";
      this.cost = 0;
      this.radius = 0;
   }

   //The method I am concerned/talking about
   public void setValue(String key, Object value)
   {
      if (key.equalsIgnoreCase("color"))
      {
         this.color = (String)value;
      }
      else if (key.equalsIgnoreCase("cost"))
      {
         this.cost= (float)value;
      }
      else if (key.equalsIgnoreCase("radius"))
      {
         this.radius = (double)value;
      }
   }
}

这被认为是不好的形式吗?我有一个来自用户的键(字符串)来标识他们想要修改的属性/字段,然后我有另一个字符串(值)来指示他们想要将其更改为的值。我确定我可以使用反射,但是

A)我听说过它的糟糕形式并且不赞成

B) It requires perfect accuracy in terms of variable names. So if I have 'appleColor', and the user puts 'applecolor', it won't work. Or, if I have 'applecolor' and I want the user to just be able to put in 'color', etc.

I'm wondering if there is a more structured/object oriented/useful way to do this. I thought about perhaps having each class that requires 'setValue()' to have a HashMap that matches a property/field to it's string key, but I'm not sure if that should be achieved through a method such as 'getHashMap()' that returns a hashmap with

hashMap.put("color", color)... or what.

Any help would be appreciated, even if it's just pointing me in the direction of a design pattern that handles this issue.

4

1 回答 1

0

You want the program to instinctively know what property to map to? That's not feasible. If you don't want to use reflection libraries, do your own and work the key the way you want.

Compare the keys ignoring the case and using the contains I guess.

Here is an algorythm that can help you, change it at your taste:

public static T Cast<T>(this Object myobj)
    {
        Type objectType = myobj.GetType();
        Type target = typeof(T);
        var x = Activator.CreateInstance(target, false);
        var z = from source in objectType.GetMembers().ToList() where source.MemberType == MemberTypes.Property select source;
        var d = from source in target.GetMembers().ToList() where source.MemberType == MemberTypes.Property select source;
        List<MemberInfo> members = d.Where(memberInfo => d.Select(c => c.Name).ToList().Contains(memberInfo.Name)).ToList();
        PropertyInfo propertyInfo;
        object value;
        foreach (var memberInfo in members)
        {
            propertyInfo = typeof(T).GetProperty(memberInfo.Name);
            PropertyInfo _prop = myobj.GetType().GetProperty(memberInfo.Name);
            if (_prop != null)
            {
                value = _prop.GetValue(myobj, null);
                try
                {
                    propertyInfo.SetValue(x, value, null);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }
        }
        return (T)x;
    }
于 2013-02-28T16:36:55.170 回答