如何定义命名参数C#

这似乎是一个简单的问题,但由于某种原因,我无法在任何地方找到答案。 基本上,我希望能够实现一个带NamedParameters的构造函数

通过命名参数,我不是指具有默认值(可选参数)的参数,例如:

public SomeMethod(){ string newBar = Foo(bar2 : "customBar2"); } public string Foo(string bar1 = "bar1", bar2 = "bar2" ){ //... } 

我想要实现的一个很好的例子是System.Web.Mvc程序集中AuthorizeAttribute 。 您可以使用以下方式:

 [Authorize(Roles = "Administrators", Users = "ThatCoolGuy")] public ActionResult Admin(){ } 

intellisense中构造函数的签名类似于以下示例,我相信(请确认)那些NamedParameters正在映射到类属性。

AuthorizeAttribute.AuthorizeAttribute( NamedParameters … )Initiliaze System.Web.Mvc.AuthorizeAttribute类的新实例

命名参数:

  • 订单int
  • 用户字符串
  • 角色字符串

您所讨论的行为特定于属性,不能在“普通”类构造函数中重用。

请注意:

调用方法时定义参数名称的语法与可选参数无关:

你可以使用Foo(bar1 : "customBar1"); 即使Foo声明如下: void Foo(string bar1)


回答这个问题:
我的猜测是,这是与Visual Studio 2010中引入的对象初始化程序类似的语法糖,因此您不能将它用于您自己的类。

你不需要“实施”任何东西。

参数可以按照您在构造函数中作为参数的现有描述的方式使用。

它们确实需要在引入时使用C#3.5或更高版本。

您的示例将在C#4.0 / Visual Studio 2010上编译和运行,无需修改。

请参阅MSDN上的命名和可选参数(C#编程指南) 。


关于对象的属性,没有相应的构造函数参数,确切的语法是特定于属性的,并且无法复制,但是,使用对象初始值设定项,您可以接近。

您可以将构建器/构造函数信息模式与属性初始值设定项一起使用。

 class PersonInfo { public string Name { get; set; } public int? Age { get; set; } public Color? FavoriteColor { get; set; } public Person BuildPerson() { return new Person(this); } } class Person { public Person(PersonInfo info) { // use info and handle optional/nullable parameters to initialize person } ... } var p = new Person(new PersonInfo { Name = "Peter", Age = 15 }); // yet better var p = new PersonInfo { Name = "Peter", Age = 15 }.BuildPerson(); 

但是我不明白,为什么你不只是使用命名参数并提供null来指示可选参数。

 class Person { public Person(string name = null, int? age = null, Color? favoriteColor = null) { /* ... */ } } var p = new Person(name: "Peter", age: 15); 

我怀疑这是可能的。 这是属性特有的。

我认为最接近的选择是使用对象初始化器:

 class Foo { public string Name {get;set;} public int Data {get;set;} } var foo = new Foo {Name = "MyName", Data = 12}; 

尝试使用此签名

 [AttributeUsage(AttributeTargets.Class)] 

在你的class级名称之前

有关完整说明,请参阅MSDN规范:

https://msdn.microsoft.com/en-us/library/aa664614(v=vs.71).aspx

属性类的每个非静态公共读写字段和属性都定义了属性类的命名参数 ”。

命名参数不是特定于属性的。 它是一种可以在任何地方使用的语言语法。 为初始化程序使用属性很好,但您并不总是希望将内部设置为set属性。

只需使用以下方法实例化您的课程:

 TheClass c = new Theclass(param3:firstValue, param1:secondValue, param2:secondValue); 

关于这部分问题:

“但是我不明白,为什么你不只是使用命名参数并提供null来指示可选参数。”

命名参数的原因很好,你不需要在括号中提供无关的值,只需要指定的内容,因为如果它是可选的,你甚至不需要输入null。 此外,如果指定null,则覆盖该参数的任何默认值,使其成为可选参数。 是可选的意味着有一个默认值意味着什么都没有传入。

实例时的属性初始化纯粹是为了方便起见。 由于C已经能够在构造时对类型进行初始化。 如果在构造函数中无法指定这些值,那么这很方便。 我个人认为,他们的便利已经破坏了人们,它变得有点过于自由,让所有公共场所得到和设置。 仅取决于您需要的属性的设计和安全性。

Visual C#2010引入了命名和可选参数。 命名参数能够通过将参数与参数名称相关联而不是参数列表中参数的位置来指定特定参数的参数。命名参数使您无需记住或查找参数的顺序。被调用方法的参数列表。

 static void Main(string[] args) { mapingFunction(snum2: "www.stackoverflow.com", num1: 1); } public static void mapingFunction(int num1, string snum2) { Console.WriteLine(num1 + " and " + snum2); } 

在这里,您可以看到该参数与我们的订单一起传递

您可能想要做的是在属性中实现公共属性:

 public class AuditFilterAttribute : ActionFilterAttribute { public string Message { get; set; } public AuditFilterAttribute() { } } 

可以通过命名参数访问它们:

 [AuditFilter(Message = "Deleting user")] public ActionResult DeleteUser(int userId) 

希望有帮助……