Универсальный метод Add в классе, состоящий из нескольких списков - PullRequest
0 голосов
/ 13 октября 2018

У меня есть класс, состоящий из нескольких списков, и у меня есть универсальные методы, позволяющие мне выполнять CRUD (и другие) операции над этими списками.

Я в основном пытаюсь сделать вариант DbContext.Set<T>с List.

Это моя ситуация:

public class A
{
    private IList<B> Bs;
    private IList<C> Cs;

    public A()
    {
        Administrators = new List<B>();
        Developers = new List<C>();
    }

    public void Add<T>(T entity)
    {
        var propertyIWant = this.GetType().GetProperties().Where(p => p.GetType() == typeof(IList<T>));
        var propertyAsList = propertyIWant as List<T>;
        propertyAsList.Add(entity);
    }

    public void Delete<T>(T entity)
    {
       //Same idea 
    }

    //Other methods
}

Проблема в том, что мой код дает мне список нужного типа, но не фактический список (то есть собственность).Поэтому любые модификации этого списка не изменяют свойство.

Я бы хотел иметь возможность сделать что-то похожее на A.List<T>, чтобы получить список этого типа (как DbContext может сделать с DbContext.Set<T>).

1 Ответ

0 голосов
/ 13 октября 2018

Вы допустили несколько ошибок здесь.

  1. Bs и Cs - это поля, а не свойства, поэтому вы должны использовать GetFields.

  2. Bs и Cs являются частными, поэтому вы должны использовать флаги привязки NonPublic и Instance

  3. Результат, полученный от Whereэто IEnumerable<T>.Вы должны позвонить FirstOrDefault или SingleOrDefault, чтобы получить информацию об одном поле.

  4. После получения информации о поле вам нужно позвонить GetValue, чтобы получить значение поля.

  5. p.GetType() возвращает typeof(FieldInfo), а не объявленный тип поля.Вместо этого вы должны использовать FieldType.

Вот исправленная версия:

public void Add<T>(T entity)
{
    var fieldIWant = this.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Where(p => p.FieldType == typeof(IList<T>)).SingleOrDefault();
    if (fieldIWant != null) {
        var value = (IList<T>)fieldIWant.GetValue(this);
        value.Add(entity);
    }
}

Или, как сказал thehennyy в комментариях, вы, вероятно, должны посмотреть на выражениедеревья, в частности MemberExpression с, чтобы сделать это.Отражение довольно медленное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...