Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的可选委托#_C#_C# 4.0_Delegates_Optional Parameters - Fatal编程技术网

C# C语言中的可选委托#

C# C语言中的可选委托#,c#,c#-4.0,delegates,optional-parameters,C#,C# 4.0,Delegates,Optional Parameters,这是两个扩展方法重载的简单示例 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<i

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

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));
    }
}
公共静态类扩展
{
公共静态IEnumerable偶数(此列表编号)
{
返回数字。其中(num=>num%2==0);
}
公共静态IEnumerable偶数(此列表编号,谓词)
{
返回数字。其中(num=>num%2==0&&谓词(num));
}
}
通过将委托设置为可选,我希望能够将它们合并为一个:

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; }
}
公共静态类扩展
{
公共静态IEnumerable偶数(此列表编号,谓词=alwaysTrue)
{
返回数字。其中(num=>num%2==0&&谓词(num));
}
公共静态bool-alwaysTrue(inta){return true;}
}
但是,编译器会抛出一个错误:

“谓词”的默认参数值必须是编译时常量

我不知道我的alwaysTrue函数是如何不是常数的,但嘿,编译器更清楚:)


有没有办法使委托参数成为可选的?

它不是常量,因为您已从方法组创建了委托。。。就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));
}
private静态只读谓词AlwaysTrue=ignored=>true;
公共静态列表偶数(此列表编号,
谓词(谓词=null)
{
谓词=谓词??始终;
返回数字。其中(num=>num%2==0&&谓词(num));
}
(您仍然可以将
AlwaysTrue
设置为一个方法并使用方法组转换,但通过只创建一次委托实例,上述方法的效率会略微提高。)

甚至公开静态列表(此列表编号,谓词谓词=null)
{
返回数字。其中(num=>num%2==0&&(谓词==null | |谓词(num));
}

您要做的是允许它为
null
,然后将其视为始终正确

您有两个选项,将代码加倍以省去委托调用,这将在不传递委托的情况下执行得更快

public static List<int> Even(this List<int> numbers, Predicate<int> predicate = null)
{
    if (predicate == null)
        return numbers.Where(num=> num % 2 == 0).ToList();
    else
        return numbers.Where(num=> num % 2 == 0 && predicate(num)).ToList();
}
看起来是这样写的:

var even = list.Even(null);

如果现在再次将方法更改为重载,如果未重新编译上述调用,则它将始终调用具有委托的方法,只为该参数提供
null

可以使用
null
-默认值:

public static class Extended 
{
    public static IEnumerable<int> Even(this IEnumerable<int> numbers, 
                                        Predicate<int> predicate = null)
    {
        if (predicate==null)
        {
            predicate = i=>true;
        }

        return numbers.Where(num => num % 2 == 0 && predicate(num));
    }
}
公共静态类扩展
{
公共静态IEnumerable偶数(此IEnumerable数字,
谓词(谓词=null)
{
if(谓词==null)
{
谓词=i=>true;
}
返回数字。其中(num=>num%2==0&&谓词(num));
}
}

有时我希望这样会有多个接受。所有的答案都是正确的,但是Jon的答案似乎对我最有利,因为他让我去阅读有关方法组的文章,以便真正了解一些我不知道的东西。为什么你说作为匿名方法,
AlwaysTrue
比命名方法更有效?我不理解你的方法组转换部分<代码>谓词=谓词??一贯的AlwaysTrue是一个方法,也可以编写code>,在
谓词
为空的情况下,调用方法。即使这样,委托也只创建一次,对吗?现在是关于命名方法和匿名方法的比较。后者是否更有效?@nawfal:使用字段意味着当您调用
甚至
时,它不会创建新的委托实例,因为它会重用该字段中的委托实例。使用方法组转换时,假设
谓词
为null,这将在每次调用时创建一个新的委托实例-委托不会被缓存。
var even = list.Even();
var even = list.Even(null);
public static class Extended 
{
    public static IEnumerable<int> Even(this IEnumerable<int> numbers, 
                                        Predicate<int> predicate = null)
    {
        if (predicate==null)
        {
            predicate = i=>true;
        }

        return numbers.Where(num => num % 2 == 0 && predicate(num));
    }
}