反射:获取在参数Object中实现接口的所有属性

时间:2018-07-24 15:05:25

标签: c# reflection

我有一个包含许多其他类对象的类:

public class Rootobject
{
    public USD USD { get; set; }
    public CAD CAD { get; set; }
    public EUR EUR { get; set; }
    public AED AED { get; set; }
    public AFN AFN { get; set; }
    public ALL ALL { get; set; }
}

这些类中的每一个都实现一个名为ICurrency的接口; ICurrency接口具有一个名为“ symbol”的字符串属性,如下所示:

public class EUR : ICurrency 
{/*code logic*/}

最后,我有一个以RootObject实例为参数的方法;

public object Add22(Rootobject rootobject)
{}

我需要获取rootobject变量中传递的所有实例的“ symbol”属性的所有值。

我认为通过创建ICurrency的列表并添加其中的所有对象然后遍历它可以很容易地通过反射来完成。

我是对的吗?如果是的话;那怎么做呢?还是有更好的方法?

1 个答案:

答案 0 :(得分:4)

您可以使用Type.GetProperties获取类型的属性,并使用Type.IsAssignableFrom查找是否可以将属性分配给ICurrency变量。您可以使用LINQ查询检索所有匹配的属性:

var currencyProps=typeof(Rootobject).GetProperties()                                   
                   .Where(pi=>typeof(ICurrency).IsAssignableFrom(pi.PropertyType))
                   .ToArray();

var currencyProps=( from pi in typeof(Rootobject).GetProperties()                                   
                    where typeof(ICurrency).IsAssignableFrom(pi.PropertyType)
                  ).ToArray();

您可以将currencyProps数组缓存在静态字段中,然后将其与任何对象重复使用:

static PropertyInfo[] _currencyProps;

static void InitializeCurrencyProps()
{
    var currencyProps=( from pi in typeof(RootObject).GetProperties()                                   
                        where typeof(ICurrency).IsAssignableFrom(pi.PropertyType)
                        select pi);
    _currencyProps=currencyProps.ToArray();
}

拥有所有想要的PropertyInfo对象后,可以使用PropertyInfo.GetValue从特定实例读取属性值,例如:

_currencyProps[0].GetValue(rootObject);

要查找具有值的所有属性(即非空值),可以使用另一个查询:

var values=_currencyProps.Select(pi=>new {pi.Name,Value=pi.GetValue(rootobject)})
                        .Where(val=>val.Value!=null)
                        .ToArray();

var values = ( from pi in _currencyProps
               let value=pi.GetValue(rootobject)
               where value !=null
               select new {pi.Name,value}
             ).ToArray();

您可以使用ToDictionary()创建字典,而不是创建数组:

var values = ( from pi in _currencyProps
               let value=pi.GetValue(rootobject)
               where value !=null
               select new {pi.Name,Value=value}
             ).ToDictionary(pair=>pair.Name,pair=>pair.Value);

var usd=values["USD"];