【发布时间】:2017-08-16 15:21:54
【问题描述】:
我很好奇是否可以使用 LINQ 语句或 lambda 来实现以下内容。我对两者都很陌生,所以我不太确定它是如何编码的。目的是拥有一个 Func 委托,我可以向其添加多个回调,并将它们全部评估为所有返回值的布尔 AND 表达式。一个优选的解决方案将允许单个错误来短路其余的评估。我以蛮力的方式实现了这一点,代码和输出如下所示:
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace TestHarness
{
public partial class Form1 : Form
{
Func<bool, bool, bool, bool> validPosition;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
validPosition += Func1;
validPosition += Func2;
validPosition += Func3;
Delegate[] delegates = validPosition.GetInvocationList();
bool composite = true;
int i = 0;
foreach (Func<bool, bool, bool, bool> d in delegates)
{
composite = composite & d(false, true, true);
if (!composite)
break;
++i;
}
Debug.WriteLine("Result: " + composite + "\tIterations: " + i);
composite = true;
i = 0;
foreach (Func<bool, bool, bool, bool> d in delegates)
{
composite = composite & d(true, false, true);
if (!composite)
break;
++i;
}
Debug.WriteLine("Result: " + composite + "\tIterations: " + i);
composite = true;
i = 0;
foreach (Func<bool, bool, bool, bool> d in delegates)
{
composite = composite & d(true, true, false);
if (!composite)
break;
++i;
}
Debug.WriteLine("Result: " + composite + "\tIterations: " + i);
composite = true;
i = 0;
foreach (Func<bool, bool, bool, bool> d in delegates)
{
composite = composite & d(true, true, true);
if (!composite)
break;
++i;
}
Debug.WriteLine("Result: " + composite + "\tIterations: " + i);
}
bool Func1(bool a, bool b, bool c)
{
return a;
}
bool Func2(bool a, bool b, bool c)
{
return b;
}
bool Func3(bool a, bool b, bool c)
{
return c;
}
}
}
Output:
Result: False Iterations: 0
Result: False Iterations: 1
Result: False Iterations: 2
Result: True Iterations: 3
感谢您的任何建议。
【问题讨论】:
-
虽然这里是主题;你可以考虑去 CodeReview.SE 解决工作代码问题
-
我没有看到任何蛮力。你真的需要这些计数吗?
-
如果您将其简化为简单的谓词
Func<T,bool>,您可以通过&&运算符将它们链接起来,并受益于它的短路特性。但我不确定你想要达到什么目的。更大的图景是什么? -
“有一个 Func 委托,我可以向其中添加多个回调”——在我看来,这个要求迫使您采用
GetInvocationList()方法。请解释要求,或者您为什么认为即使有该要求,也可能有替代解决方案。坦率地说,到目前为止,这个问题要么“不清楚”,要么“太宽泛”。 -
这样做的最终目的是在游戏中具有不同类型的可安装对象,这些对象具有 1 到 n 个标准来确定是否可以将其放置在特定图块上。该类使用组合而不是继承,“Wall”类型的对象只有一个标准 - 瓷砖是空的吗? “门”类型的可安装对象具有标准 - 瓷砖是空的吗?南北有墙,还是东、西有墙?当可安装对象被实例化时,“n”个回调将被添加到其回调 Func 委托中,该委托应按上述方式进行评估。
标签: c# linq lambda boolean expression