studio - Cómo definir los parámetros nombrados C#
see cref c# (10)
Esto parece una pregunta simple, pero por alguna razón no puedo encontrar la respuesta en ningún lado. Básicamente, me gustaría poder implementar un constructor que tome NamedParameters .
Por parámetros nombrados, no me refiero a parámetros con valores predeterminados (parámetros opcionales) como:
public SomeMethod(){
string newBar = Foo(bar2 : "customBar2");
}
public string Foo(string bar1 = "bar1", bar2 = "bar2" ){
//...
}
Un buen ejemplo de lo que estoy tratando de lograr es el AuthorizeAttribute del ensamblado System.Web.Mvc . Que se puede utilizar de la siguiente manera:
[Authorize(Roles = "Administrators", Users = "ThatCoolGuy")]
public ActionResult Admin(){
}
La firma del constructor en intellisense se parece al siguiente ejemplo y creo (por favor, confirme) que esos NamedParameters se asignan a las propiedades de la clase.
AuthorizeAttribute.AuthorizeAttribute ( NamedParameters ... ) Inicia la nueva instancia de la clase System.Web.Mvc.AuthorizeAttribute
Parámetros nombrados:
- Orden int
- Cadena de usuarios
- Cadena de roles
Consulte la especificación de MSDN para una descripción completa:
https://msdn.microsoft.com/en-us/library/aa664614(v=vs.71).aspx
" Cada propiedad y campo público no estático de lectura y escritura para una clase de atributo define un parámetro con nombre para la clase de atributo ".
Dudo que sea posible. Esto es algo específico para los atributos.
Creo que la opción más cercana es usar un inicializador de objetos:
class Foo {
public string Name {get;set;}
public int Data {get;set;}
}
var foo = new Foo {Name = "MyName", Data = 12};
El comportamiento del que habla es específico para los atributos y no se puede reutilizar en los constructores de clases "normales".
Lo que probablemente quieras hacer es implementar propiedades públicas en tu atributo:
public class AuditFilterAttribute : ActionFilterAttribute
{
public string Message { get; set; }
public AuditFilterAttribute() { }
}
Se puede acceder a ellos a través de Parámetros con nombre donde lo apliques:
[AuditFilter(Message = "Deleting user")]
public ActionResult DeleteUser(int userId)
Espero que ayude...
Los parámetros nombrados NO son específicos a los atributos. Es una sintaxis de lenguaje que se puede utilizar en todas partes. Está bien usar propiedades para los inicializadores, pero no siempre desea que los elementos internos se configuren como propiedades establecidas.
Solo instancia tu clase usando:
TheClass c = new Theclass(param3:firstValue, param1:secondValue, param2:secondValue);
Con respecto a esta parte de la pregunta:
"Sin embargo, no entiendo, por qué no solo utiliza parámetros con nombre y proporciona un valor nulo para indicar parámetros opcionales".
La razón por la que los parámetros nombrados son agradables es que no es necesario que proporcione valores extraños entre paréntesis, solo lo que desea especificar, porque si es opcional, no debería tener que poner un valor nulo. Además, si especifica nulo, está anulando cualquier valor predeterminado para ese parámetro que lo hace opcional. Ser opcional implica que hay un valor predeterminado que significa que no se pasa nada.
La inicialización de la propiedad en el momento de la instancia es puramente para su conveniencia. Desde C, ha habido la capacidad de inicializar valores en el momento de la construcción en tipos. Lo que es útil si esos valores no se pueden especificar en el constructor. Personalmente, siento que la conveniencia de ellos ha arruinado a la gente y se vuelve un poco demasiado liberal y hace que todo sea público y establezca. Solo depende del diseño y seguridad de las propiedades que necesite.
No necesitas "implementar" nada.
Los parámetros se pueden usar de la manera que describe simplemente existiendo como parámetros en el constructor.
Debe utilizar C # 3.5 o superior, cuando se introdujeron.
Su ejemplo se compilará y ejecutará en C # 4.0 / Visual Studio 2010 sin modificaciones.
Consulte Argumentos con nombre y opcionales (Guía de programación de C #) en MSDN.
En lo que respecta a las propiedades en el objeto, que no tienen argumentos de constructor correspondientes, la sintaxis exacta es específica de los atributos y no se puede replicar, sin embargo, con los inicializadores de objetos puede acercarse.
Puede usar el patrón de información constructor / constructor junto con los inicializadores de propiedades.
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();
Sin embargo, no entiendo, por qué no solo utiliza parámetros con nombre y proporciona un valor nulo para indicar parámetros opcionales.
class Person
{
public Person(string name = null, int? age = null, Color? favoriteColor = null) { /* ... */ }
}
var p = new Person(name: "Peter", age: 15);
Tenga en cuenta:
La sintaxis de definir el nombre del parámetro al llamar a un método no tiene nada que ver con los parámetros opcionales:
Puedes usar Foo(bar1 : "customBar1");
incluso si Foo
se declara así: void Foo(string bar1)
Para responder a la pregunta:
Supongo que este es un azúcar sintáctico similar a los inicializadores de objetos introducidos en Visual Studio 2010 y, por lo tanto, no puede usar esto para sus propias clases.
Visual C # 2010 introduce argumentos nombrados y opcionales. El argumento con nombre le permite especificar un argumento para un parámetro en particular asociando el argumento con el nombre del parámetro en lugar de con la posición del parámetro en la lista de parámetros. Los argumentos con nombre le exigen la necesidad de recordar o buscar el orden de los parámetros en el Listas de parámetros de los métodos llamados.
static void Main(string[] args)
{
mapingFunction(snum2: "www..com", num1: 1);
}
public static void mapingFunction(int num1, string snum2)
{
Console.WriteLine(num1 + " and " + snum2);
}
Aquí se puede ver que los argumentos se pasan con nuestra orden de ellos.
intenta usar esta firma
[AttributeUsage(AttributeTargets.Class)]
antes del nombre de tu clase