我想编写一个函数,可以在将值插入List之前完成一些检查。 例如:
class Person {
public string Name { get; set; }
public int Value { get; set; }
public Guid Id { get; set; }
}
-------
var persons = new List<Person>();
// add a new person if John doesn't exist
persons.AddIf(s => !s.Name.Equals("John"), new Person { ... });
----
public static void AddIf(this List<T> lst, Func<T, bool> check, T data)
{
// how can I use the Func 'check' to check if exist an object with the
// information that the client wrote and, if not exists, insert the new value
// into the list???
if ( check )
}
如何使用Func'check'检查是否存在具有客户端编写信息的对象,如果不存在,则将新值插入列表中?
答案 0 :(得分:11)
您需要使您的方法通用。
public static void AddIf<T>(this List<T> lst, Func<T, bool> check, T data)
{
if (!lst.All(check))
return;
lst.Add(data);
}
和你想要的用法(所有项目都应该满足谓词):
persons.AddIf(s => !s.Name.Equals("John"), new Person { ... });
答案 1 :(得分:0)
对于你自己的语义,你有一个可以依赖的答案。但对我来说,这个方法命名是混淆的,我想的就越多。 AddIf
表示是否添加或添加全部?在你的情况下,这就是全部。所以你应该更好地命名它。 AddIfAll
或其他什么。
要添加到列表中,如果不存在某些内容是一个常见的要求,我建议的是为了您的目的而更加充实(我相信),这使得来电者更容易。
可能是
public static bool AddIfNotContains<S, T>(this ICollection<S> lstObject,
Func<S, T> selector, T valueToMatch,
S objectToAdd)
{
if (lstObject.Contains(selector, valueToMatch))
return false;
lstObject.Add(objectToAdd);
return true;
}
我更喜欢在我的程序中使用的Contains
超载:
public static bool Contains<S, T>(this IEnumerable<S> lstObject,
Func<S, T> comparer, T valueToMatch)
{
return lstObject.Any(s => comparer(s).Equals(valueToMatch));
}
这避免了每次都从我们这边写Equals
操作员的麻烦。
您可以致电:
persons.AddIfNotContains(s => s.Name, "John", new Person { ... });
我认为这使语法更简单。
我希望你知道这里的问题。你可以写得很好
persons.AddIfNotContains(s => s.Name, "John", new Person { Name = "Serena", .. });
即使已存在名为Serena
的人,因为您正在检查John
。如果那对你好,那么好。 如果我正确理解您的问题,那么更好的实施方式是:
public static bool AddIfTrulyNotContains<S, T>(this ICollection<S> lstObject,
Func<S, T> selector, S objectToAdd)
{
if (lstObject.Contains(selector, selector(objectToAdd)))
return false;
lstObject.Add(objectToAdd);
return true;
}
现在你可以轻松打电话了:
persons.AddIfTrulyNotContains(s => s.Name, new Person { Name = "John", .. });
这只会检查John
,如果列表中没有John
则会添加。另外,我已将返回类型设为bool
以表示添加。
答案 2 :(得分:0)
快速组合/更改上述答案,并附上一些评论:(我的代表太低而不能简单地评论脸红)
所以,基于问题示例中的某些细节:
如何使用Func'check'检查是否存在具有的对象 客户编写的信息,如果不存在,则插入新信息 值列入名单?
1)我肯定会考虑创建/使用通用扩展,专门用于在添加到列表(而不是打开“check”)之前检查重复项(如所提到的,常见操作),所以可能是这样的:
public static void AddIfDistinct<T>(this List<T> lst, T data, Func<T, bool> dupeCheck)
{
if (lst.Any(dupeCheck))
return;
lst.Add(data);
}
2)根据要求,“Any”在语义上比“All”更清晰,在我看来 - 我们正在检查“任何”重复,而不是检查“所有”当前项目是否“不”重复......这可能听起来微不足道,但我认为可以说它更为明显。这显然意味着你传入的lambda看起来像这样(这里的语义变化意味着你必须得到名为well的扩展方法)
s => s.Name.Equals("John")
3)最后评论,如果合适的话,你也可以覆盖你的课上的一些东西,如“CompareTo”等,并创建一个非常通用的“AddToListIfUnique”等
此外,使用表达式&lt; FUNC&LT; ...&GT;&GT;在你的例子中根本没有帮助(正如有人建议的那样),因为你无论如何都在使用List(只有你使用IQueryable等时才值得)