Подтвердить что ты не робот

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

Это похоже на простой вопрос, но по какой-то причине я не могу найти ответ нигде. В принципе, я хотел бы иметь возможность реализовать конструктор, который принимает 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
  • Строка пользователей
  • Строка ролей
4b9b3361

Ответ 1

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

Ответ 2

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

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

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


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

Ответ 3

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

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

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

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

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


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

Ответ 4

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

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

Ответ 5

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

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

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

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

Ответ 6

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

[AttributeUsage(AttributeTargets.Class)]

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

Ответ 7

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

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

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

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

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

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

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

Ответ 8

Visual С# 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);
}

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

Ответ 9

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

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

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

Ответ 10

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

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

    public AuditFilterAttribute() { }
}

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

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

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