How to define named Parameters C#

纵然是瞬间 提交于 2019-12-03 23:33:23

问题


This seems like a simple question, but for some reason I can't find the answer anywhere. Basically, I'd like to be able to implement a constructor that takes NamedParameters.

By named parameters, I do not mean parameters with default values (optional parameters) such as:

public SomeMethod(){
    string newBar = Foo(bar2 : "customBar2");
}

public string Foo(string bar1 = "bar1", bar2 = "bar2" ){
     //...
}

A good example of what I'm trying to achieve is the AuthorizeAttribute from the System.Web.Mvc assembly. Which you can use the following way:

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

}

The constructor's signature in intellisense looks like the following example and I believe (please confirm) that those NamedParameters are mapping to class properties.

AuthorizeAttribute.AuthorizeAttribute(NamedParameters...) Initiliaze new instance of the System.Web.Mvc.AuthorizeAttribute class

Named parameters:

  • Order int
  • Users string
  • Roles string

回答1:


The behaviour you are talking about is specific for attributes and cannot be reused in "normal" classes constructors.




回答2:


Please note:

The syntax of defining the parameter name when calling a method has nothing to do with optional parameters:

You can use Foo(bar1 : "customBar1"); even if Foo is declared like this: void Foo(string bar1)


To answer the question:
My guess is that this is syntactic sugar similar to the object initializers introduced in Visual Studio 2010 and therefore you can't use this for your own classes.




回答3:


You don't need to "implement" anything.

The parameters can be used in the manner you describe just by existing as parameters on the constructor.

You do need to be using C# 3.5 or above, when they were introduced.

Your example will compile and run on C# 4.0 / Visual Studio 2010 without modification.

See Named and Optional Arguments (C# Programming Guide) on MSDN.


In regards to properties on the object, that do not have a corresponding constructor arguments, the exact syntax is specific to attributes and can't be replicated, though, with object initializers you can get close.




回答4:


You can use the builder/constructor info pattern together with property initializers.

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();

I however don't understand, why you don't just use named parameters and provide null for indicating optional parameters.

class Person
{
    public Person(string name = null, int? age = null, Color? favoriteColor = null) { /* ... */ }
}

var p = new Person(name: "Peter", age: 15);



回答5:


I doubt that's possible. This is something specific for attributes.

I think the closest option is to use an object initializer:

class Foo {
    public string Name {get;set;}
    public int Data {get;set;}
}

var foo = new Foo {Name = "MyName", Data = 12};



回答6:


try to use this signature

[AttributeUsage(AttributeTargets.Class)]

before the name of your class




回答7:


Please refer to MSDN specification for full description:

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

"Each non-static public read-write field and property for an attribute class defines a named parameter for the attribute class".




回答8:


Named parameters are NOT specific to attributes. It's a language syntax that can be used everywhere. It's fine to use properties for initialisers but you don't always want to have internals set as set properties.

Just instantiate you class using:

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

With regards to this part of the question:

"I however don't understand, why you don't just use named parameters and provide null for indicating optional parameters."

The reason named parameters are nice is you don't need to provide extraneous values in parentheses, just what you want to specify, because if it's optional you shouldn't even need to put null. Furthermore, if you specify null, you are overriding any default value for that parameter which makes it optional. Being optional implies there's a default value meaning nothing passed in.

Property initialisation at instance time is purely there for convenience. Since C there has been the ability to initialise values at construction time on types. Which is handy if those values can't be specified in the constructor. I personally feel that the convenience of them has spoiled people and it get a little too liberal and make everything public get AND set. Just depends on the design and security of properties you need.




回答9:


Visual C# 2010 introduces named and optional arguments. Named argument able you to specify an argument for a particular parameter by associating the argument with the parameter's name rather than with the parameter's position in the parameter list.Named arguments free you from the need to remember or to look up the order of parameters in the parameter lists of called methods.

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);
}

here you can see that argument are passed with our their order




回答10:


What you probably want to do is implement public properties in your attribute:

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

    public AuditFilterAttribute() { }
}

They can be accessed through Named Parameters where you apply it:

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

Hope that helps...



来源:https://stackoverflow.com/questions/12056639/how-to-define-named-parameters-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!