C#.Net 4.0命名和默认参数

时间:2009-03-26 15:39:53

标签: c# c#-4.0

您认为在C#.Net 4.0中添加了什么值的命名和默认参数?

对于这些(在重载和覆盖时尚未实现)有什么用处?

6 个答案:

答案 0 :(得分:4)

它可以使构造函数更简单,特别是对于不可变类型(对于线程很重要) - see here for a full discussion。不像应该那么好,但比有很多重载更好。你显然不能将对象初始化器与不可变对象一起使用,所以通常会这样:

new Foo {Id = 25, Name = "Fred"}

不可用;我会满足于:

new Foo (Id: 25, Name: "Fred")

这可以扩展到简化重载的一般想法,但在大多数情况下,我更喜欢过载宣传合法组合。构造函数有点不同,IMO,因为您只是(通常)定义初始状态。

事情的COM方面对很多人来说也很重要,但我根本就没有使用太多的COM互操作 - 所以这对我来说不是


编辑评论;为什么他们只使用属性使用的相同语法?简单 - 它可能与其他成员/变量不一致(这不是属性的问题);举个例子:

[XmlElement("foo", Namespace = "bar")]

使用一个常规参数(对ctor,“foo”)和一个命名赋值。因此,假设我们将此用于常规命名参数:

SomeMethod("foo", SecondArg = "bar");

(也可能是构造函数;为简单起见,我使用了一种方法)

现在......如果我们有一个名为SecondArg的变量或属性怎么办?使用SecondArg作为SomeMethod的命名参数,将“bar”分配给SecondArg,并将“bar”作为常规参数传递之间的含义不明确

为了说明这一点,这在C#3.0中是合法的:

    static void SomeMethod(string x, string y) { }
    static void Main()
    {
        string SecondArg;
        SomeMethod("foo", SecondArg = "bar");
    }

显然,SecondArg可以是属性,字段,变量等......

替代语法没有这种歧义。

<小时/> 编辑 - 280Z28的这一部分:很抱歉在这里添加这个,但它并不是一个独特的答案,它对于评论来说太长了,包括代码。你暗示了模棱两可,但你的例子没有强调决定性案例。我认为你给出的例子指出了可能令人困惑的事情,但是所需的{}对象初始化器可以防止潜在的语法模糊。我对以下代码的解释是作为多行块注释嵌入的。

[AttributeUsage(AttributeTargets.Class)]
public sealed class SomeAttribute : Attribute
{
    public SomeAttribute() { }

    public SomeAttribute(int SomeVariable)
    {
        this.SomeVariable = SomeVariable;
    }

    public int SomeVariable
    {
        get;
        set;
    }
}

/* Here's the true ambiguity: When you add an attribute, and only in this case
 * there would be no way without a new syntax to use named arguments with attributes.
 * This is a particular problem because attributes are a prime candidate for
 * constructor simplification for immutable data types.
 */

// This calls the constructor with 1 arg
[Some(SomeVariable: 3)]
// This calls the constructor with 0 args, followed by setting a property
[Some(SomeVariable = 3)]
public class SomeClass
{
}

答案 1 :(得分:1)

这将有助于避免提供合适的API来使用Office应用程序的问题! :)

Office API的某些部分是可以的,但是有一些边缘情况明确设计为可以从具有可选/命名参数的语言中使用。所以这就是C#必须拥有它们的原因。

答案 2 :(得分:1)

可选参数还可以避免类提供许多方法的问题,这些方法只是接受的参数的变体。

考虑Exception类。它不是一个带有可选参数的构造函数,而是为'has message'和'具有内部异常'的每个组合提供了四个构造函数。那没关系,但是现在考虑一下如果你为一个带有innerException的构造函数提供一个空值会发生什么?它是否与没有innerException参数的构造函数完全相同,类似于没有innerException参数的构造函数,或者是否抛出空引用异常?

具有2个可选参数的单个构造函数会更明显地传递null innerException等同于根本不包含它。默认参数的理想位置。

另外不要忘记现在每个派生的Exception类也必须包含4个构造函数,这是一个毫无意义的麻烦。

答案 3 :(得分:0)

它将使COM互操作变得更加容易。

直到C#4 VB.Net是一个更好的互操作语言。如果没有默认值,您可以在C#中使用大量的伪引用参数列表。

答案 4 :(得分:0)

代码的简洁性是人们想到的明显的代码。为什么在定义一个函数时定义几个重载。但是,如果您有两个相同类型的参数,则无法始终构建您可能需要的完整重载集。

答案 5 :(得分:0)

这也不能编译:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute(object a = null)
    {

    }
}


class Test
{
    [My] // [My(a: "asd")]
    int prop1 { get; set; }
}

虽然这样做:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute()
    {

    }

    public object a { get; set; }
}

class Test
{
    [My] // [My(a=null)]
    int prop1 { get; set; }
}