C# 中的可选委托 [英] Optional delegates in C#
问题描述
这是两个扩展方法重载的简单示例
This is a simple example of two extension methods overloads
public static class Extended
{
public static IEnumerable<int> Even(this List<int> numbers)
{
return numbers.Where(num=> num % 2 == 0);
}
public static IEnumerable<int> Even(this List<int> numbers, Predicate<int> predicate)
{
return numbers.Where(num=> num % 2 == 0 && predicate(num));
}
}
我希望能够通过将委托设置为可选来将它们合并为一个:
I'd like to be able to merge them into one, by setting a delegate to be optional:
public static class Extended
{
public static IEnumerable<int> Even(this List<int> numbers, Predicate<in> predicate = alwaysTrue)
{
return numbers.Where(num=> num % 2 == 0 && predicate(num));
}
public static bool alwaysTrue(int a) { return true; }
}
然而,编译器抛出一个错误:
However, compiler throws an error:
谓词"的默认参数值必须是编译时常量
Default parameter value for 'predicate' must be a compile-time constant
我不明白我的 alwaysTrue 函数如何不是常量,但是嘿,编译器知道得更好:)
I don't see how my alwaysTrue function is not constant, but hey, compiler knows better :)
有什么办法可以让委托参数成为可选的吗?
Is there any way to make the delegate parameter optional?
推荐答案
它不是常量,因为您从方法组创建了一个委托……就 C# 语言而言,这不是编译时常量.
It's not constant because you've created a delegate from a method group... that's not a compile-time constant as far as the C# language is concerned.
如果你不介意稍微滥用 null
的含义,你可以使用:
If you don't mind abusing the meaning of null
slightly you could use:
private static readonly Predicate<int> AlwaysTrue = ignored => true;
public static List<int> Even(this List<int> numbers,
Predicate<int> predicate = null)
{
predicate = predicate ?? AlwaysTrue;
return numbers.Where(num=> num % 2 == 0 && predicate(num));
}
(您可以仍然使 AlwaysTrue
成为一个方法并使用方法组转换,但是上面的方法通过创建稍微效率更高委托实例只有一次.)
(You could still make AlwaysTrue
a method and use a method group conversion, but the above approach is very slightly more efficient by creating the delegate instance just once.)
这篇关于C# 中的可选委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!