FastMember ObjectReader не работает с унаследованными интерфейсами

Я получаю интерфейс как возвращение из библиотеки, которую я не могу контролировать:

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. Я подтвердил это, сделав тест и имея B в IA непосредственно.

Я нашел очень плохой обходной путь, который включает в себя создание нового класса, который реализует 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 ответ

Я клонировал репозиторий пакета FastMember, в TypeAccessor класс I изменил строку 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 (), чтобы вернуть все свойства для иерархии наследования интерфейса

Это сработало для меня.

Другие вопросы по тегам