c# - 委托(delegate)组合不当行为

标签 c# delegates

给出以下代码:

List<string> aux = new List<string>();

aux.Add("a");
aux.Add("ab");
aux.Add("ac");
aux.Add("abc");
aux.Add("b");
aux.Add("bc");
aux.Add("c");
aux.Add("e");
aux.Add("f");

Func<string, bool> searchForA = (f => f.Contains("a"));
Func<string, bool> searchForC = (f => f.Contains("c"));
Func<string, bool> searchForF = (f => f.Contains("f"));

谁能给我解释一下为什么打这个电话

aux.Where(searchForA + searchForF + searchForC).ToList();

返回“ac”、“abc”、“bc”和“c”,结果与

相同
aux.Where(searchForC).ToList();

我的意思是,第一个查询中的“a”、“ab”和“F”在哪里?

编辑:我使用委托(delegate)组合是因为我想动态定义搜索模式!

EDIT2:对新示例代码的主要编辑检查,这是我试图解决的问题

string[] searchFor = "a c f".Split(' ');

Func<string, bool>[] delegates = new Func<string, bool>[searchFor.Length];
for (int i = 0; i < searchFor.Length; i++)
{
    string search = searchFor[i]; // Make sure the lambda does not capture a loop variable!
    delegates[i] = new Func<string, bool>(f => f.Contains(search));
}

List<string> aux = new List<string>(); 
aux.Add("a");
aux.Add("ab");
aux.Add("ac");
aux.Add("abc");
aux.Add("b");
aux.Add("bc");
aux.Add("c");
aux.Add("e");
aux.Add("f");

List<string> result = aux.Where((Func<string, bool>)Delegate.Combine(delegates)).ToList();

最佳答案

调用两个非 void 返回委托(delegate)的组合具有“调用第一个,丢弃结果,调用第二个,返回结果”的语义。它没有语义“如果它们恰好返回 bool,则同时调用它们和 结果”。请记住,委托(delegate)组合必须适用于任何委托(delegate)类型;为什么运行时应该为返回 bool 的委托(delegate)选择 语义而不是 语义?它应该为返回 string 的委托(delegate)做什么,连接字符串?如果您组合 int 返回委托(delegate),它应该添加数字吗?

合并结果的问题无法以一致的方式解决,因此选择忽略除最后一个以外的所有结果。

如果您想将两个谓词 放在一起,那么您可以自己轻松完成。这是一个方便的扩展方法:

static Func<T, bool> Or<T>(this Func<T, bool> f1, Func<T, bool> f2)
{ return t => f1(t) || f2(t); }

现在你可以说

...Where(searchForA.Or(searchForC).Or(searchForF))...

您还可以将其扩展到多个委托(delegate):

static Func<T, bool> OrMany<T>(params Func<T, bool>[] fs)
{ 
    Func<T, bool> result = t => false;
    foreach(Func<T, bool> f in fs)
        result = result.Or(f);
    return result;
}

现在您可以使用带有委托(delegate)列表的“扩展形式”:

...Where(OrMany(searchForA, searchForC, searchForf))...

或带有委托(delegate)数组的“未扩展形式”:

Func<string, bool>[] delegates = whatever;
...Where(OrMany(delegates))...

关于c# - 委托(delegate)组合不当行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15257873/

相关文章:

c# - 如何通过 SSL 从 LDAP 获取 DirectoryEntry?

swift - 在 Swift 中为更多 View Controller 自定义 TableView ?

ios - GameCenter 通知干扰 iAd View

c# - 请求后 WebClient 中的 header 消失

c# - 获取字符串的子串

ios - UIDocumentPickerViewController - 未调用委托(delegate)方法

objective-c - 核心图1.0 : Provide Custom Labels for Legends

c# - 如何从 Action 中返回值

c# - 更改/导航到树的特定节点?

javascript - 如何使用DTO实现上传功能?