函数重载与可选参数

时间:2013-05-28 10:07:37

标签: c# overloading optional-parameters

所以我只是考虑函数重载...

  

重载的方法共享相同的名称,但具有唯一的签名。参数的数量,参数的类型或两者必须不同。不能仅根据不同的返回类型重载函数。

所以在下面的例子中,为什么重载setName而不是使用中间名和姓氏值的可选参数?

class funOverload
{
    public string name;

    //overloaded functions
    public void setName(string last)
    {
        name = last;
    }

    public void setName(string first, string last)
    {
        name = first + "" + last;
    }

    public void setName(string first, string middle, string last)
    {
        name = first + "" + middle + "" + last;
    }

    //Entry point
    static void Main(string[] args)
    {
        funOverload obj = new funOverload();

        obj.setName("barack");
        obj.setName("barack "," obama ");
        obj.setName("barack ","hussian","obama");

    }
}

至少,使用以下内容可以减少需要编写的代码量:

public void setName(string first, string middle = "", string last = "")
{
   name = first + "" + middle + "" + last;

   // name = "barack" + "" + "";
}

//Entry point
static void Main(string[] args)
{
    funOverload obj = new funOverload();

    // could optionally set middle and last name values here as well
    obj.setName("barack");
 }

我理解重载的概念,但我不知道为什么它比使用可选参数更合适(或反之亦然)。

任何人都可以解释一下吗?

仅供参考,这是我重载的第一个函数:http://pastebin.com/ynCuaay1
此功能允许您在有或没有参数列表的情况下调用MySqlContext.GetReader() ...我认为它使代码比必须始终致电GetReader(sql, args.ToArray())更整洁

2 个答案:

答案 0 :(得分:1)

  

我不明白为什么它比使用可选参数更理想的选择

具有默认值的参数有一些限制,在某些情况下这可能很重要。

您可以为引用类型设置默认参数,而不是null(string参数除外):

class Foo
{
    public int Id { get; set; }
}

class Bar
{
    public Bar(Foo parent)
    {
    }

    public Bar()
        : this(new Foo { Id = 1 }) // this can't be done with default parameters
    {
    }
}

具有默认值的参数不能出现在常规参数之前,有时这可能是合适的:

class Foo
{
    public void Method(int i, string s, bool b) { }
    public void Method(string s, bool b) 
    {
        Method(0, s, b); // this can't be done with default parameters
    }
}

答案 1 :(得分:0)

在您的示例中,三个重载与具有可选参数的方法不同。 setName(string last)声明给出的最小数据是姓氏,其中public void setName(string first, string middle = "", string last = "")不允许您省略名字。如果要在使用可选参数调用方法时省略中间名,则必须使用setName("barack", last: "obama")

使用带有可选参数的方法会更好一些:

public void setName(string last, string first= "", string middle = "")

但这会破坏名称的自然顺序,并允许您设置中间名而不指定三个重载禁止的第一个(setName("barack", middle: "hussein");)。