FastMember ObjectReader不适用于继承的接口

时间:2016-12-20 11:19:42

标签: c# fastmember

我从一个我无法控制的库中返回一个接口:

public interface IA : IB { String A { get;} }
public interface IB { String B { get;} }

现在,当我尝试运行此代码时,我得到一个例外:

List<IA> list = library.Get();
IDataReader r = ObjectReader.Create(list, nameof(IA.A), nameof(IA.B));
while (r.Read())
{
    for (Int32 i = 0; i < r.FieldCount; i++)
    {
        //HERE ArgumentOutOfRangeException: Specified argument was out of the range of valid values.Parameter name: name
        Object o = r[i];
        Console.Write(o + ",");
    }
    Console.WriteLine();
}

它似乎找不到B属性,因为它在IB中声明。我通过进行测试并直接在IA中确认了B来证实这一点。

我发现了一个非常糟糕的解决方法,它涉及创建一个实现IA的新类:

public class Ab : IA
{
    public Ab(String a, String b)
    {A = a;B=b;}

    public String A { get;}
    public String B { get;}
}

然后将List<IA>转换为:List<Ab> newList = l.Select(e => new Ab(e.A, e.B).ToList(),然后转换为ObjectReader.Create(newList)。我这样做时,ObjectReader似乎找到了B属性。但是,在资源(以及大量代码)上创建具有完全相同内容的中间对象似乎非常浪费。

是否有可能以另一种方式解决不涉及创建新对象的问题?

1 个答案:

答案 0 :(得分:2)

我克隆了FastMember软件包的存储库,在TypeAccessor类中,我将265行更改为:

PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);

收件人:

PropertyInfo[] props = GetPrpsInterfaces(type, BindingFlags.Public | BindingFlags.Instance).ToArray();

替换功能的实现:

static IEnumerable<PropertyInfo> GetPrpsInterfaces(Type type, BindingFlags flags)
{
      if (!type.IsInterface)
           return type.GetProperties(flags);

      return (new Type[] { type }).Concat(type.GetInterfaces()).SelectMany(i => i.GetProperties(flags));
}

我在这里找到: GetProperties() to return all properties for an interface inheritance hierarchy

这对我有用。