Именованные параметры C # .Net 4.0 и параметры по умолчанию - PullRequest
3 голосов
/ 26 марта 2009

Как вы думаете, какое значение именованные и параметры по умолчанию добавят в C # .Net 4.0?

Что было бы полезно для них (что еще не было достигнуто с перегрузкой и переопределением)?

Ответы [ 6 ]

4 голосов
/ 26 марта 2009

Это может упростить конструкторы, особенно для неизменяемых типов (которые важны для многопоточности) - полное обсуждение см. Здесь . Не так хорошо, как , должно быть , возможно, но лучше, чем иметь много перегрузок. Очевидно, вы не можете использовать инициализаторы объектов с неизменяемыми объектами, поэтому обычно:

new Foo {Id = 25, Name = "Fred"}

недоступно; Я согласен на:

new Foo (Id: 25, Name: "Fred")

Это может быть расширено до общей идеи упрощения перегрузок, но в большинстве случаев я бы предпочел перегрузки, которые рекламируют допустимые комбинации. IMO, конструкторы немного отличаются, поскольку вы (обычно) определяете начальное состояние.

COM-сторона вещей также важна для многих людей, но я просто не использую COM-взаимодействие - так что это не , как , важно для меня.


Редактировать повторные комментарии; почему они просто не использовали тот же синтаксис, что и атрибуты? Просто - это может быть неоднозначно с другими членами / переменными (что не является проблемой с атрибутами); возьмите пример:

[XmlElement("foo", Namespace = "bar")]

, который использует один обычный параметр (для ctor, "foo") и одно именованное присваивание. Итак, предположим, что мы используем это для обычных именованных аргументов:

SomeMethod("foo", SecondArg = "bar");

(который также может быть конструктором; для простоты я использовал метод)

Теперь ... что если у нас есть переменная или свойство с именем SecondArg? Это было бы неоднозначно между использованием SecondArg в качестве именованного аргумента для SomeMethod и назначением "bar" для SecondArg и передачей "bar" в качестве обычного аргумента .

Для иллюстрации, это допустимо в C # 3.0:

    static void SomeMethod(string x, string y) { }
    static void Main()
    {
        string SecondArg;
        SomeMethod("foo", SecondArg = "bar");
    }

Очевидно, что SecondArg может быть свойством, полем, переменным и т. Д ...

Альтернативный синтаксис не имеет этой неоднозначности.

<ч /> Редактировать - этот раздел на 280Z28: Извините, что добавил это сюда, но это не совсем уникальный ответ, он слишком длинный для комментариев и включает код. Вы намекнули на неоднозначность, но ваш пример не выдвинул на первый план решающий случай. Я думаю, что пример, который вы привели, указывает на то, что может сбивать с толку, но требуемый {} вокруг инициализаторов объектов предотвращает основную синтаксическую неоднозначность. Мое объяснение следующего кода встроено в многострочный блочный комментарий.

[AttributeUsage(AttributeTargets.Class)]
public sealed class SomeAttribute : Attribute
{
    public SomeAttribute() { }

    public SomeAttribute(int SomeVariable)
    {
        this.SomeVariable = SomeVariable;
    }

    public int SomeVariable
    {
        get;
        set;
    }
}

/* Here's the true ambiguity: When you add an attribute, and only in this case
 * there would be no way without a new syntax to use named arguments with attributes.
 * This is a particular problem because attributes are a prime candidate for
 * constructor simplification for immutable data types.
 */

// This calls the constructor with 1 arg
[Some(SomeVariable: 3)]
// This calls the constructor with 0 args, followed by setting a property
[Some(SomeVariable = 3)]
public class SomeClass
{
}
<Ч />
1 голос
/ 26 марта 2009

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

Рассмотрим класс исключения. Вместо одного конструктора с необязательными аргументами у него есть четыре конструктора для каждой комбинации «имеет сообщение» и «имеет внутреннее исключение». Это нормально, но теперь рассмотрим, что произойдет, если вы предоставите нулевое значение конструктору, принимающему innerException? Действует ли он точно так же, как конструктор без параметра innerException, sortof как конструктор без параметра innerException, или он генерирует исключение нулевой ссылки?

Один конструктор с 2 необязательными параметрами сделал бы более очевидным, что передача нулевого внутреннего исключения равносильна тому, чтобы вообще не включать его. Идеальное место для аргументов по умолчанию.

Также не забывайте, что теперь каждый производный класс Exception также должен включать 4 конструктора, что бесполезно.

1 голос
/ 26 марта 2009

Это поможет избежать проблемы с предоставлением достойного API для работы с приложениями Office! :)

Некоторые части Office API в порядке, но есть крайние случаи, которые были явно разработаны для использования с языком с необязательными / именованными параметрами. Вот почему C # должен иметь их.

0 голосов
/ 23 января 2012

Также это не компилируется:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute(object a = null)
    {

    }
}


class Test
{
    [My] // [My(a: "asd")]
    int prop1 { get; set; }
}

в то время как это делает:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute()
    {

    }

    public object a { get; set; }
}

class Test
{
    [My] // [My(a=null)]
    int prop1 { get; set; }
}
0 голосов
/ 26 марта 2009

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

0 голосов
/ 26 марта 2009

Это значительно упростит COM-взаимодействие.

До C # 4 VB.Net был гораздо лучшим языком для взаимодействия. Без значений по умолчанию у вас есть огромный список фиктивных параметров ссылок в C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...