Значение по умолчанию для обнуляемого значения в c # 2.0 - PullRequest
20 голосов
/ 21 ноября 2011

Используя C # 2.0, я могу указать значение параметра по умолчанию следующим образом:

static void Test([DefaultParameterValueAttribute(null)] String x) {}

Поскольку этот синтаксис C # 4.0 недоступен:

static void Test(String x = null) {}

Итак, есть ли эквивалент C # 2.0 для типов значений? Например:

static void Test(int? x = null) {}

Следующие попытки не компилируются.

// error CS1908: The type of the argument to the DefaultValue attribute must match the parameter type
static void Test([DefaultParameterValueAttribute(null)] int? x) {}

// error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression
static void Test([DefaultParameterValueAttribute(new Nullable<int>())] int? x) {}

Ответы [ 5 ]

14 голосов
/ 21 ноября 2011

К сожалению, старые версии компилятора C # не поддерживают это.

Компилятор C # 4.0 компилирует это:

public static void Foo(int? value = null)

Into:

public static void Foo([Optional, DefaultParameterValue(null)] int? value)

По сути, это то же самое, что и ваша первая попытка (с добавлением OptionalAttribute, кроме того), в которой компилятор C # 2 допускает ошибки с CS1908, поскольку это не было поддержано непосредственно в этой версии компилятора.

Если вам нужна поддержка C # 2, в этом случае я бы рекомендовал вместо этого добавить перегруженный метод:

static void Test()
{
    Test(null);
}
static void Test(int? x)
{
    // ..
10 голосов
/ 21 ноября 2011

Рид, конечно, правильно; Я просто подумал добавить интересный факт о угловом корпусе. В C # 4.0 вы можете сказать: (для структуры типа S)

void M1(S x = default(S)) {}
void M2(S? x = null) {}
void M3(S? x = default(S?)) {}

Но, как ни странно, вы не можете сказать

void M4(S? x = default(S)) {}

В первых трех случаях мы можем просто генерировать метаданные, которые говорят, что «необязательное значение является значением по умолчанию типа формального параметра». Но в четвертом случае необязательным значением является значение по умолчанию другого типа . Не существует очевидного способа кодирования такого рода фактов в метаданные. Вместо того, чтобы придумать единообразное правило для языков о том, как кодировать такой факт, мы просто сделали его незаконным в C #. Вероятно, это редкий случай, так что нет больших потерь.

2 голосов
/ 21 ноября 2011

Очевидно, вы не можете использовать этот атрибут.

Как вы знаете, параметры атрибута «сериализуются» в метаданные во время компиляции - поэтому вам нужно постоянное выражение.Поскольку компилятору не нравится 'null', у вас нет параметров.

Что вы можете сделать - перегрузить - определить другой метод Text без параметров, который вызывает ваш метод Text с нулем

0 голосов
/ 21 ноября 2011

Я считаю, что это должно быть:

static void Text(int? x = default(int?));
0 голосов
/ 21 ноября 2011

Работает ли это: [DefaultParameterValueAttribute((int?)null)]?Пробовал - это тоже не работает (

...