Фильтр с троичным оператором - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть метод

AddOrUpdateList(this List<T> list, T scope, Func<T, bool>, Func<T, bool> when = null){
    T item = default;
    if (when == null)
        list.SingleOrDefault(t => t.Equals(scope)); //Check Single
    else
        item = list.SingleOrDefault(when);
    .
    .
    .
}

Когда я собираюсь его использовать, у меня есть два возможных запуска:

  1. Я получаю element, что element.Title что-то, поэтому я использую Title в качестве фильтра
  2. Я получаю element, который не имеет заголовка, поэтому мне нужно получить последний из списка

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

Я придумал следующее:

var filter = (element.Title != "")
   ? (Func<T, bool>)(e => e.Title == element.Title)
   : (Func<T, bool>)(e = list.Select(ele => ele).Last());

Но это дает мне: Error CS0030 Cannot convert type 'T' to 'System.Func<T, bool>'

Любая идея или помощь, которую вы можете мне дать ??

Я довольно новичок в C# и Linq, так что я не очень хорошо понимаю, как некоторые вещи должны работать

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Ваш текущий фильтр

var filter = (element.Title != "")
   ? (Func<T, bool>)(e => e.Title == element.Title)
   : (Func<T, bool>)(e = list.Select(ele => ele).Last());

Но e = list.Select(ele => ele).Last() не Func<T, bool>. На самом деле это не функция вообще. Как сказал @ canton7, вам нужно использовать обозначение стрелки (=>), чтобы создать лямбду. Более того, даже если бы эта строка была лямбда-выражением, она бы имела тип Func<T, T>, поскольку она просто возвращает последний элемент в списке элементов типа T; он вообще не возвращает bool!

Это больше, чем вы хотите?

var filter = (element.Title != "")
   ? (Func<T, bool>)(e => e.Title == element.Title)
   : (Func<T, bool>)(e => e.Title == list.Last().Title);
0 голосов
/ 18 февраля 2020

Какой тип element? Так, AddOrUpdateList(Func<T, bool>) использует T как тип некоторого обобщенного c кода. Когда у вас есть конкретный элемент, вы должны знать, какой тип кода. И установите конкретное имя класса.

Если вы покажете больше кода, я постараюсь вам помочь.

Может быть, я выхожу из бизнеса, но это кажется странным. В соответствии с именем метода, вы хотите добавить элемент, если он не существует, или обновить его, если он уже есть в списке.

Итак, вот пример типичной реализации такого метода.

public void AddOrUpdate<T, K>(this List<T> list, T element, Func<T, K> keySelector, Action<T, T> mapFunction) : T new()
{
    var elementKey = keySelector(element);
    var elementForUpdate = list.FirstOrDefault(x => keySelector(x) == elementKey);

    var exists = elementForUpdate != null;

    if (!exists)
    {
        var newElement = new T();
        list.Add(newElement);
        elementForUpdate = list.Last();
    }

    mapFunction(elementForUpdate, element);
}

Итак, тогда в другой части кода вы можете использовать его так:

...
var itemToAdd = new ClassWithTitle { Title = "Title 1"};
list.AddOrUpdate(itemToAdd , x => x.Title, (destination, origin) =>
{
    //Logic to map fields
    destination.Title = origin.Title;
    destination.SomeOtherField = origin.SomeOtherField;
})
...

Пожалуйста, обратите внимание.

Еще один вариант, если вы работаете со списком (не с базой данных), вы можете использовать метод IndexOf(), тогда этот метод будет очень простым.

public void AddOrUpdate<T, K>(this List<T> list, T element, Func<T, K> keySelector)
{
    var elementKey = keySelector(element);
    var elementFounded = list.FirstOrDefault(x => keySelector(x) == elementKey);

    var exists = elementForUpdate != null;

    if (!exists)
    {
        //IMPORTANT: Here you add element that sended to method. You should take it into consideration. 
        //If you want to add a clone of this object, implement interface IClonable and use this method like   list.Add(element.Clone());
        list.Add(element);
        return;
    }

    var indexOfFoundedElement = list.IndexOf(elementFounded);

     //IMPORTANT: Here you replace element that sended to method. You should take it into consideration. 
    list[indexOfFoundedElement] = element;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...