C#中的可选委托

Kor*_*tak 15 c# delegates optional-parameters c#-4.0

这是两个扩展方法重载的简单示例

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));
    }
}
Run Code Online (Sandbox Code Playgroud)

通过将委托设置为可选,我希望能够将它们合并为一个:

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; }
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器会抛出错误:

'predicate'的默认参数值必须是编译时常量

我没有看到我的alwaysTrue函数是如何不是常量的,但是嘿,编译器知道的更好:)

有没有办法让delegate参数可选?

Jon*_*eet 19

它不是常量,因为你已经从方法组创建了一个委托......就C#语言而言,这不是编译时常量.

如果您不介意滥用含义,null可以使用:

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));
}
Run Code Online (Sandbox Code Playgroud)

(你可以仍然做AlwaysTrue的方法和使用方法组转换,但上述做法是非常轻微更有效的创建委托实例只有一次.)