委托的概念对我来说并不新鲜,但我似乎无法找到如何从Func委托中获得所有结果。更具体地说,我有一个类,它有一个返回bool类型的Func委托。像这样的。。。
private Func<Employee, Shift, bool> qualificationCheckCallback;
回调也有"register"one_answers"unregister"方法。我的目标是查看存储在委托中的任何方法在稍后的代码中调用时是否返回false。非常感谢您对这个问题的任何见解!谢谢
您使用了错误的模式。我建议存储这些委托的列表并在列表上迭代,而不是使用多个委托来调用多个目标。
您可以通过更改签名以包含一个"状态"变量来实现这一点(如果需要的话),该变量通过引用传递给每个调用者:
private Action<Employee, Shift, QualCheckState> qualificationCheckCallback;
public class QualCheckState { public bool Passed { get; set; } }
// Call it thus:
var state = new QualCheckState { Passed = true }; // Hope for the best
qualificationCheckCallback(someEmployee, someShift, state);
if (state.Passed) {
// Assume everyone passed
}
请记住,这需要被调用者遵守签名,而不是覆盖其他人的失败状态:
public void SomeCallee(Employee e, Shift s, State state) {
// If some other check failed, don't bother doing our check.
if (!state.Passed) return;
// Do some check here
if (checkFailed) state.Passed = false;
}
当然,您也可以扩展此模式以使其更安全:
public class QualCheckState {
private List<bool> _results = new List<bool>();
public bool Passed { get { return _results.All(s => s); }
public void RecordResult(bool result) {
_results.Add(result);
}
}
正如Andrew的回答中所提到的,如果像普通方法一样简单地调用qualificationCheckCallback
,则只能从其中一个方法返回返回值。因此,具有返回值的多播委托是非常不寻常的。
如果您的目标是查看存储在委托中的方法中是否至少有一个返回false,则需要单独调用这些方法。以下是使用Delegate.GetInvocationList()方法实现这一点的一种方法:
bool hasAtLeastOneFalse = false;
if (qualificationCheckCallback != null)
{
foreach(var f in qualificationCheckCallback.GetInvocationList()
.Cast<Func<Employee, Shift, bool>>())
{
if (!f(employee, shift))
{
hasAtLeastOneFalse = true;
// break; // If you don't care about invoking all delegates, you can choose to break here.
}
}
}
Console.WriteLine(hasAtLeastOneFalse);
我并不是说这是一个好的做法,但它是可以做到的。
在MSDN上快速搜索发现了以下线程:
https://social.msdn.microsoft.com/Forums/en-US/38a638fe-4a7d-44d6-876c-729d90c20737/how-to-get-return-value-from-delegate?forum=csharplanguage
事件的问题是返回值不能完全值得信赖。无论返回值有多少,您都只能得到一个您拥有的活动订阅者。核心问题是您无法可靠地确定是哪个订阅者生成了回报价值.NET事件模型的美妙之处在于它的匿名性使用。这意味着事件订阅者完全从事件发布者。