Как определить именованные параметры C #

17

Это похоже на простой вопрос, но по какой-то причине я не могу найти ответ нигде. В принципе, я хотел бы иметь возможность реализовать конструктор, который принимает NamedParameters .

По названным параметрам я не имею в виду параметры со значениями по умолчанию (необязательные параметры), например:

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

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

Хорошим примером того, что я пытаюсь достичь, является AuthorizeAttribute из сборки System.Web.Mvc . Что вы можете использовать следующим образом:

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

}

Подпись конструктора в intellisense выглядит следующим образом, и я считаю (пожалуйста, подтвердите), что эти NamedParameters сопоставляются с свойствами класса.

  

AuthorizeAttribute.AuthorizeAttribute ( NamedParameters ... )   Инициализировать новый экземпляр класса System.Web.Mvc.AuthorizeAttribute

     

Именованные параметры:

     
  • Заказать int
  •   
  • Строка пользователей
  •   
  • Строка ролей
  •   
    
задан Pierluc SS 21.08.2012 в 16:04
источник

10 ответов

14

Поведение, о котором вы говорите, специфично для атрибутов и не может быть использовано повторно в конструкторах «нормальных» классов.

    
ответ дан mathieu 21.08.2012 в 16:08
источник
15

Обратите внимание:

Синтаксис определения имени параметра при вызове метода не имеет ничего общего с необязательными параметрами:

Вы можете использовать Foo(bar1 : "customBar1"); , даже если Foo объявлено следующим образом: void Foo(string bar1)

Чтобы ответить на вопрос:
Я предполагаю, что это синтаксический сахар, похожий на инициализаторы объектов , представленный в Visual Studio 2010, и поэтому вы не можете использовать его для своих собственных классов.

    
ответ дан Daniel Hilgarth 21.08.2012 в 16:12
источник
6

Вам не нужно ничего «реализовывать».

Параметры могут использоваться в том виде, который вы описываете, только существуя как параметры в конструкторе.

Вы do должны использовать C # 3.5 или выше, когда они были введены.

Ваш пример будет скомпилирован и запущен на C # 4.0 / Visual Studio 2010 без изменений.

См. Именованные и необязательные аргументы (Руководство по программированию на C #) в MSDN.

Что касается свойств объекта, которые не имеют соответствующих аргументов конструктора, то точный синтаксис специфичен для атрибутов и не может быть реплицирован, однако, с инициализаторы объектов , вы можете приблизиться.

    
ответ дан Oded 21.08.2012 в 16:10
источник
3

Вы можете использовать шаблон информации о конструкторе / конструкторе вместе с инициализаторами свойств.

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);
    
ответ дан Sebastian Graf 21.08.2012 в 16:06
источник
1

Я сомневаюсь, что это возможно. Это нечто специфическое для атрибутов.

Я думаю, что самым близким вариантом является использование инициализатора объекта:

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

var foo = new Foo {Name = "MyName", Data = 12};
    
ответ дан Jensen 21.08.2012 в 16:11
источник
0

попытайтесь использовать эту подпись

[AttributeUsage(AttributeTargets.Class)]

перед именем вашего класса

    
ответ дан Diogo de Freitas nunes 02.10.2013 в 17:08
источник
0

Пожалуйста, обратитесь к спецификации MSDN для полного описания:

Ссылка

" Каждое нестатическое публичное поле для чтения и записи для свойства класса атрибута определяет именованный параметр для класса атрибутов .

    
ответ дан rahnema1 12.07.2016 в 15:45
источник
0

Именованные параметры НЕ относятся к атрибутам. Это синтаксис языка, который можно использовать повсюду. Хорошо использовать свойства для инициализаторов, но вы не всегда хотите, чтобы внутренние настройки задавались как заданные свойства.

Просто создайте экземпляр класса, используя:

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

В отношении этой части вопроса:

  

«Я, однако, не понимаю, почему вы не просто используете именованные параметры и указываете null для указания необязательных параметров».

Причины, по которым названы параметры, хороши, вам не нужно предоставлять посторонние значения в круглых скобках, просто то, что вы хотите указать, потому что, если это необязательно, вам даже не нужно указывать нуль. Кроме того, если вы укажете null, вы переопределите любое значение по умолчанию для этого параметра, что делает его необязательным. Будучи факультативным, существует значение по умолчанию, означающее, что ничего не прошло.

Инициализация имущества во время экземпляра чисто для удобства. Поскольку C была возможность инициализировать значения во время построения по типам. Это удобно, если эти значения не могут быть указаны в конструкторе. Я лично чувствую, что удобство их испортило людей, и оно становится слишком либеральным и делает все, что угодно, получает и устанавливает. Просто зависит от дизайна и безопасности необходимых вам свойств.

    
ответ дан Stephen York 07.04.2014 в 03:52
источник
0

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

здесь вы можете увидеть, что этот аргумент передан нашим нашим порядком

    
ответ дан Adiii 19.01.2015 в 14:14
источник
0

Что вы, вероятно, захотите сделать, это реализовать публичные свойства в вашем атрибуте:

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

    public AuditFilterAttribute() { }
}

Доступ к ним можно получить через Именованные параметры, где вы его применяете:

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

Надеюсь, что это поможет ...

    
ответ дан Fred Mauroy 29.11.2017 в 15:32
источник