Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可拓方法、T的Func和T的List_C#_Generics_Lambda_Extension Methods - Fatal编程技术网

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也没有任何帮助(正如有人建议的),因为您无论如何都在使用List(只有在使用IQueryable等时才有价值)

对于泛化,我会使用Expression。方法的语义不好。如果不是条件,你就添加条件。@KirillBestemyanov同意并删除。顺便说一句,这里的利益表达式树将给出什么?
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")