0

我想通过名称访问属性值。我知道它的唯一方法是使用这样的代码进行反射:

 public static object GetPropValue(object src, string propName)
 {
     return src.GetType().GetProperty(propName).GetValue(src, null);
 }

还有其他方法吗(使用ex.codegen等)?

4

1 回答 1

1

我知道它的唯一方法是使用这样的代码进行反射:

反射是一种方式,它也很昂贵(所以我听说过),所以你创建一个缓存来加速多个属性查找(这就是所做的)。类似的东西(完全示例代码):

private static Dictionary<PropertyInfoKey, PropertyInfo> propertyCache = 
  new Dictionary<PropertyInfoKey, PropertyInfo>()

private class PropertyInfoKey : IEquatable 
{
  public PropertyInfoKey(string fullName, string propertyName)
  {  
    FullName = fullName;
    PropertyName = propertyName
  }

  public string FullName { get; private set; }
  public string PropertyName { get; private set; }

  public bool Equals(PropertyInfoKey other)
  {
    if ( ..// do argument checking

    var result = FullName == other.FullName
      && PropertyName == other.PropertyName;

    return result;
  }
}

public static bool TryGetPropValue<T>(T src, 
  string propName, 
  out object value)
  where T : class
{
  var key = new PropertyInfoKey(
    fullName: typeof(T).FullName,
    propertyName: propName
  );

  PropertyInfo propertyInfo;
  value = null;
  var result = propertyCache.TryGetValue(key, out propertyInfo);

  if (!result)
  {
    propertyInfo = typeof(T).GetProperty(propName);

    result = (propertyInfo != null);

    if (result)
    {
      propertyCache.Add(key, propertyInfo)
    }  
  }

  if (result)
  {
    value = propertyInfo.GetValue(src, null);
  }
  return result;
}

(*也许你可以使用 aHashSet代替,因为 PropertyInfoKey 在技术上也可以持有PropertyInfo,并且它正在实施IEquatable

或者....

如果您这样做是因为您有很多具有相似属性但完全不同且不相关的类......

public interface IName
{
  public string Name { get; }
}

public class Car : IName
{
  public string Name { get; set; }
  public string Manufacturer { get; set; }
}

public class Animal : IName
{
  public string Name { get; set; }
  public string Species { get; set; }
}

public class Planet : IName
{
  public string Name { get; set; }
  public string ContainSystem { get; set; }
}

那么你也能

public static string GetName(this IName instance)
{
  return instance.Name;
}
于 2015-10-30T20:29:15.987 回答