C# 可拓方法、T的Func和T的List
我想编写一个函数,可以在将值插入列表之前完成一些检查。 例如:C# 可拓方法、T的Func和T的List,c#,generics,lambda,extension-methods,C#,Generics,Lambda,Extension Methods,我想编写一个函数,可以在将值插入列表之前完成一些检查。 例如: 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 person
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 )
}
班级人员{
公共字符串名称{get;set;}
公共int值{get;set;}
公共Guid Id{get;set;}
}
-------
var persons=新列表();
//如果John不存在,请添加一个新人
persons.AddIf(s=>!s.Name.Equals(“约翰”),新的persons{…});
----
公共静态无效AddIf(此列表lst、Func check、T data)
{
//如何使用Func“check”检查是否存在具有
//客户端编写的信息,如果不存在,则插入新值
//进入名单???
如果(检查)
}
如何使用Func“check”来检查是否存在包含客户端编写的信息的对象,如果不存在,则将新值插入列表中?您需要使方法具有通用性
public static void AddIf<T>(this List<T> lst, Func<T, bool> check, T data)
{
if (!lst.All(check))
return;
lst.Add(data);
}
对于你自己的语义学,你已经有了一个答案。但对我来说,方法命名越是令人困惑<代码>添加表示添加(如果有)或添加(如果全部)?在你的情况下,这就是一切。所以你应该给它起个更好的名字
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;
}
这避免了每次从我们这边编写Equals
操作符的麻烦
你可以致电:
persons.AddIfNotContains(s => s.Name, "John", new Person { ... });
我认为这使得语法更加简单
注:
我希望你知道这里的陷阱。你写得很好
persons.AddIfNotContains(s => s.Name, "John", new Person { Name = "Serena", .. });
即使已经有人叫瑟琳娜,因为你在这里检查的是约翰
。如果这对你合适,那就好了如果我正确理解您的问题,更好的实现方法是:
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;
}
这只是检查
John
并添加列表中是否没有John
。此外,我还将返回类型设置为bool
,以表示添加。快速组合/更改上述答案,并附上一些注释:(我的代表太低,无法简单地注释blush)
因此,根据问题示例中的某些细节:
如何使用Func“check”检查是否存在具有
客户端编写的信息,如果不存在,则插入新的
价值进入清单
1)我肯定会考虑在添加到列表(而不是打开的“检查”)之前专门创建/使用一个通用的扩展来检查重复(如所提到的,一个普通的操作),所以可能是这样的:
public static void AddIfDistinct<T>(this List<T> lst, T data, Func<T, bool> dupeCheck)
{
if (lst.Any(dupeCheck))
return;
lst.Add(data);
}
3) 最后一条注释,如果合适的话,您还可以覆盖类中的一些内容,比如“CompareTo”等,并创建一个真正通用的“addToListFunique”等
另外,在您的示例中使用Expression
All
将失败,如果其中任何一个不满足谓词(即,它的名称是John),并且我们不会添加新的人。好的。。。所以我需要通过条件检查我的数据。。。为什么要使用表达式???@Gaetanu您不应该在这里使用表达式。请注意,在您的示例中,您创建Person对象时不考虑谓词结果。如果您不打算在检查失败时使用此对象,您可能应该更改该方法的签名,以便仅在需要时创建Person对象。@PanosRontogiannis很可能只是一个伪变量OP。他很可能已经有了一个例子要补充,即使这个名字可能会导致错误。IEnumerable.All()
方法不会遍历整个列表。当给定func返回false时,它立即中止。它与IEnumerable.Any()
正好相反,当给定func返回true时,它会立即返回。因此编写if(!lst.Any(func))
迭代的项目数与if(lst.All(func))
迭代的项目数相同。看看MSDN上的备注部分,是的,100%正确,有业余爱好者的困惑。然而,我仍然强烈支持它,因为它更清楚地表明了我们正在努力实现的目标。将进行编辑以反映这一点…谢谢。
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", .. });
public static void AddIfDistinct<T>(this List<T> lst, T data, Func<T, bool> dupeCheck)
{
if (lst.Any(dupeCheck))
return;
lst.Add(data);
}
s => s.Name.Equals("John")