题
您认为命名参数和默认参数将在 C#.Net 4.0 中添加什么值?
这些有什么好处(尚未通过重载和重写实现)?
解决方案
它可以使构造函数更简单,特别是对于不可变类型(这对于线程很重要) - 请参阅此处进行完整讨论. 。没有它那么好 应该 或许可以,但比大量重载要好。显然,您不能将对象初始值设定项与不可变对象一起使用,因此通常:
new Foo {Id = 25, Name = "Fred"}
不可用;我会解决:
new Foo (Id: 25, Name: "Fred")
这可以扩展到简化重载的一般思想,但是在 最多 在这种情况下,我更喜欢宣传合法组合的重载。IMO,构造函数有点不同,因为您只是(通常)定义初始状态。
COM 方面对很多人来说也很重要,但我根本不使用太多 COM 互操作 - 所以这不是 作为 对我很重要。
编辑评论;为什么他们不使用与属性相同的语法?简单 - 它可能与其他成员/变量不明确(这不是属性的问题);举个例子:
[XmlElement("foo", Namespace = "bar")]
它使用一个常规参数(对于构造函数,“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
{
}
其他提示
这将有助于躲闪提供一个体面的API与Office应用程序一起工作的问题! :)
办公室API的某些部分是好的,但也有边界情况进行了明确设计用于可选/命名参数的语言使用。所以这就是为什么C#都必须有他们。
可选参数也避免该问题,其中类提供许多方法是只对接受的参数的变化。
考虑异常类。代替一个构造与可选参数的,它具有为“有消息”每个组合四个构造函数,和'具有内部异常。这是正常的,但现在考虑,如果你提供一个空值构造服用的InnerException会发生什么?它是否起到完全一样的构造与没有的InnerException参数,sortof等中也没有的InnerException参数的构造函数,或者它抛出一个空引用异常?
2个可选参数的单一的构造将使它更明显的是,通过一个空的InnerException相当于不包括它。默认参数一个完美的地方。
另外不要忘记,现在每派生异常类还必须包括4层构造,这是一个无意义的麻烦。
这将使COM互操作方便很多。
直到C#4 VB.Net是互操作一个更好的语言。如果没有缺省值你有虚设ref参数大规模列表在C#。
的代码简洁是明显的一个弹簧想到。为什么定义几个重载时,你可以定义一个函数。此外,虽然,如果你有两个相同类型的参数,它并不总是能够构建一整套你可能需要重载的。
另外,这并不编译:
[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; }
}