三元运算符过滤
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);
.
.
.
}
当我要使用它时,我有两个可能的开始:
- 我收到一个
element
,其中 element.Title
是什么,所以我使用 Title
作为过滤器
- 我收到一个没有标题的
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);
我有一个方法
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);
.
.
.
}
当我要使用它时,我有两个可能的开始:
- 我收到一个
element
,其中element.Title
是什么,所以我使用Title
作为过滤器 - 我收到一个没有标题的
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);