C#可选参数还是方法重载? [重复]

问题描述

|                                                                                                                   这个问题已经在这里有了答案:                                                      

解决方法

可选参数很好,但是应该在有意义的情况下使用。可选参数通常会混淆方法的意图-如果有其他选择,我会倾向于这种选择。 对可选参数和命名参数的部分需求是因为COM允许了可选参数和名称参数: MSDN   一些API,最著名的是COM接口   例如Office自动化API,   专门用named编写   和可选参数。上   到现在为止,   从C#调用这些API   有时多达三十个论点   必须明确通过,大多数   其中有合理的违约   值,可以省略。 来自forums.asp.net的SomeNewKid简洁地说: http://forums.asp.net/t/386604.aspx/1   ...重载方法通常   优于可选参数。   为什么?保留每种方法   目的明确。也就是说,每种方法   应该做好一件事。立刻   您引入可选参数,   稀释了它的清洁度   方法,并引入分支   最好保留的逻辑   一种方法。目的明确   当你变得更加重要   开始使用继承。如果你   覆盖具有一个或多个的方法   可选参数,它们变为   更加努力。所以,我建议   除了快速和其他   肮脏的类,您可以在   对可选参数的偏好。 请记住,可选参数是语法糖: 反射器C#:
public class Class1
{
    // Methods
    public Class1()
    {
        this.Method1(\"3\",\"23\");
    }

    public void Method1(string one,[Optional,DefaultParameterValue(\"23\")] string two)
    {
    }
}
IL:
.class public auto ansi beforefieldinit Class1
    extends [mscorlib]System.Object
{
    .method public hidebysig specialname rtspecialname instance void .ctor() cil managed
    {
        .maxstack 8
        L_0000: ldarg.0 
        L_0001: call instance void [mscorlib]System.Object::.ctor()
        L_0006: nop 
        L_0007: nop 
        L_0008: ldarg.0 
        L_0009: ldstr \"3\"
        L_000e: ldstr \"23\"
        L_0013: call instance void WebApplication1.Class1::Method1(string,string)
        L_0018: nop 
        L_0019: nop 
        L_001a: ret 
    }

    .method public hidebysig instance void Method1(string one,[opt] string two) cil managed
    {
        .param [2] = string(\'23\')
        .maxstack 8
        L_0000: nop 
        L_0001: ret 
    }

}
    ,Visual Studio和FxCop中的代码分析建议您不要在公共API中使用可选参数(规则CA1026:不应使用默认参数)。给出的原因是,并非所有.NET语言都支持它们。 我认为,避免它们的一个更好的理由是,如果在API的2.0版中添加更多重载,它们可能会引入运行时或编译时问题。 Phil Haack在这里解释。 我将采纳Phil的结论:可选参数旨在支持COM互操作。如果您不使用COM,请不要理会它们。     ,我不确定对此是否有一个规范的答案-它是主观的,视情况而定。但是,我认为可选参数会创建更明确的API,因此,与方法重载相比,我通常更喜欢它们。 具体来说,在使用Intellisense时,我更喜欢看到以下内容: 在此: 如果未指定,我可能不得不猜测(或查找文档)param1和param2的值是什么。     ,可选参数旨在促进COM对象之间的交互,因为COM对象使用许多可选参数。因此,如果您要进行P / Invoke或COM对象操作,则最好使用可选参数。否则,方法重载是正确的方法,因为它避免了很多混乱。     ,我已经变得非常喜欢对象初始化器,而不是重载或命名可选参数。该类中需要的只是一个无参数的构造函数,以及要在初始化时设置的任何内容的公共属性。 假设Bar类具有公共字符串属性\“ Name \”和\“ Pet \”,则可以像这样构造一个新对象。
var foo = new Bar { Name = \"Fred\",Pet = \"Dino\" };
这样做的好处是,对于要初始化的值的每种组合,您都不需要单独的重载。     ,可选参数需要一个默认值(我仅假设),因此在某些情况下可能很难提供一个默认值。为什么?好吧,有些类需要运行时信息进行初始化,而编译器可能无法使用这些信息。 当涉及到原始类型时,答案可能与是否可以采用默认值或是否缺少参数可能表示该方法的行为有关。