三元运算符过滤

Filter with terniary operator

我有一个方法

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,所以我需要从列表中获取最后一个

我正在考虑使用三元运算符和 lambda 来创建一个考虑这两种情况的过滤器。

我想到的是:

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 的新手,所以我不太了解某些东西应该如何工作

提前致谢。

什么类型的element?因此,AddOrUpdateList(Func<T, bool>) 使用 T 作为一些泛型代码的类型。当你有具体元素时,你应该知道什么类型的代码。并设置一个具体的 class 名称。

如果你展示更多代码,我会尽力帮助你。

可能是我倒闭了,但看起来很奇怪。根据方法名称,如果元素不存在则添加元素,如果元素已在列表中则更新它。

因此,这是典型的此类方法实现示例。

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;
}

您当前的过滤器是

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 所说,您需要使用箭头符号 (=>) 来创建一个 lambda。此外,即使该行是 lambda,它的类型也是 Func<T, T>, 因为它只是 return 类型 T 项目列表中的最后一项;它根本 return 不是布尔值!

这更是你想要的吗?

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