C#.Net 4.0命名和默认参数
您认为命名参数和默认参数将在C#.Net 4.0中添加什么值C#.Net 4.0命名和默认参数,c#,c#-4.0,C#,C# 4.0,您认为命名参数和默认参数将在C#.Net 4.0中添加什么值 对于这些(重载和重写尚未实现的)功能,有什么好的用途 这将使COM的互操作更加容易 在C#4之前,VB.Net是一种更好的互操作语言。如果没有默认设置,在C#中会有大量的伪ref参数列表。代码的简洁性是显而易见的。既然可以定义一个函数,为什么还要定义几个重载呢。另外,如果您有两个相同类型的参数,那么并不总是能够构造您可能需要的全部重载集。它可以使构造函数更简单,特别是对于不可变类型(对于线程来说很重要)-。也许没有它应该的那么好,但是
对于这些(重载和重写尚未实现的)功能,有什么好的用途 这将使COM的互操作更加容易
在C#4之前,VB.Net是一种更好的互操作语言。如果没有默认设置,在C#中会有大量的伪ref参数列表。代码的简洁性是显而易见的。既然可以定义一个函数,为什么还要定义几个重载呢。另外,如果您有两个相同类型的参数,那么并不总是能够构造您可能需要的全部重载集。它可以使构造函数更简单,特别是对于不可变类型(对于线程来说很重要)-。也许没有它应该的那么好,但是比有很多重载要好。显然,不能对不可变对象使用对象初始值设定项,因此通常:
new Foo {Id = 25, Name = "Fred"}
不可用;我会满足于:
new Foo (Id: 25, Name: "Fred")
这可以扩展到简化重载的一般思想,但在大多数情况下,我更喜欢宣传合法组合的重载。在我看来,构造函数有点不同,因为您只是(通常)定义初始状态
COM方面的东西对很多人来说也很重要,但我只是不使用太多的COM互操作,所以这对我来说并不重要
编辑重新评论;为什么它们不使用与属性相同的语法呢?简单-它可能与其他成员/变量不明确(这不是属性的问题);例如:
[XmlElement("foo", Namespace = "bar")]
它使用了一个常规参数(对于ctor,“foo”)和一个命名赋值。因此,假设我们将其用于常规命名参数:
SomeMethod("foo", SecondArg = "bar");
(也可以是构造函数;为了简单起见,我使用了一种方法)
现在。。。如果我们有一个名为SecondArg
的变量或属性,该怎么办?使用SecondArg
作为SomeMethod
的命名参数,将“bar”指定给SecondArg
,并将“bar”作为常规参数传递,这两者之间是不明确的
举例来说,这在C#3.0中是合法的:
显然,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
{
}
这将有助于避免为Office应用程序提供体面的API的问题:)
Office API的某些部分还可以,但也有一些边缘案例是为使用带有可选/命名参数的语言而设计的。这就是为什么C#必须有它们的原因。可选参数也避免了类提供几十个方法的问题,这些方法只是接受的参数的变体 考虑异常类。它不是一个带有可选参数的构造函数,而是为“has message”和“has internal exception”的每个组合使用四个构造函数。没关系,但是现在考虑如果给一个内嵌异常的构造函数提供空值会发生什么?它的行为是否与没有innerException参数的构造函数完全相同,或者与没有innerException参数的构造函数完全相同,或者它是否抛出空引用异常 带有2个可选参数的单个构造函数会使传递null innerException相当于根本不包含它变得更加明显。默认参数的完美位置
另外,请不要忘记,现在每个派生异常类还必须包含4个构造函数,这是一个毫无意义的麻烦。此外,这不会编译:
[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; }
}
是的-直到大微软咬紧牙关,生产出真正的托管操作系统(我看不到他们很快就能做到),一些应用程序将不得不处理非托管呼叫。哦,非常好。我原以为他们必须允许从初始值设定项块中分配ReadOnly,但这个想法很快就变得混乱起来。这要好得多。尽管如你所说,如果构造函数是魔术般出现的,那就太好了。我很好奇为什么他们没有借用属性使用的命名参数语法。@Marc:我在你答案的底部发布了我的回复。:)我是这么说的;)使用Office API时,VB.Net比C更容易使用#
[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; }
}