Аргумент атрибута должен быть постоянной ошибкой при использовании необязательного параметра в конструкторе атрибута - PullRequest
17 голосов
/ 28 ноября 2011

Может кто-нибудь объяснить, почему этот код работает:

public class AdministratorSettingValidationAttribute : Attribute
{
    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType)
    {
        DataType = administratorSettingDataType;
    }

    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType)
    {
        DataType = administratorSettingDataType;
        EnumerationType = enumerationType;
    }
}

... но вместо этого его рефакторинг для использования необязательного параметра:

    public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = null)
    {
        DataType = administratorSettingDataType;
        EnumerationType = enumerationType;
    }

... вызывает ошибку времени компиляции: " Аргументом атрибута должно быть постоянное выражение, выражение typeof или выражение создания массива типа параметра атрибута ".

Ответы [ 2 ]

19 голосов
/ 28 ноября 2011

ОБНОВЛЕНИЕ

Ошибка была зарегистрирована в июле прошлого года и уже исправлена.Исправление появится в следующей версии C #.См. Этот элемент обратной связи Connect для деталей:

http://connect.microsoft.com/VisualStudio/feedback/details/574497/optional-parameter-of-type-string-in-a-attribute-constructor-cannot-be-null


Это явно ошибка компилятора.Спасибо за то, что обратили на это мое внимание.

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

Вы можете обойти ошибку, превратив константу в явно типизированную:

public AdministratorSettingValidationAttribute(AdministratorSettingDataType administratorSettingDataType, Type enumerationType = (Type)null) 

Исправление, вероятно, простое, но я не могу обещать, что исправление будет в следующей версии C #;Я не уверен, каково расписание для исправления некритических ошибок на этом этапе.

Еще раз спасибо и приносим извинения за неудобства.

5 голосов
/ 28 ноября 2011

Это пахнет как ошибка компилятора для меня.Классы атрибутов являются «специальными» классами в том смысле, что их можно использовать в качестве метаданных.Компилятор C # позволяет вам использовать их не так, как обычные классы, и поэтому мы можем предположить, что в компиляторе C # существует (частичная) специальная реализация для компиляции использования классов атрибутов.(Кто-нибудь может проверить это на моно?)

Тем не менее, я провел несколько тестов и обнаружил, что только при использовании конструктора атрибута, который задает значение параметра по умолчанию как ноль, не определяя пользовательское значение этогоатрибут, компилятор выдает нам ошибку.Мой тестовый код:

class TestAttribute : Attribute
{
    public TestAttribute(object test = null) { }
    //public TestAttribute(int test = 0) { } 

    public void TestMethod(object test = null) { }
}

class TestClass
{
    public TestClass(object test  = null) { }
}

[Test()] // crashes
//[Test()] // Works when using the constructor taking an int
//[Test(null)] // works
class Program
{
    static void Main(string[] args)
    {
        TestClass t = new TestClass(); // works

        TestAttribute a = typeof(Program).GetCustomAttributes(typeof(TestAttribute), false).Cast<TestAttribute>().First();

        a.TestMethod(); // works
    }
}

(Протестировано с VS 2010 в .NET 4.0, кто-нибудь может проверить это с моно?)

Обратите внимание, что атрибуты уже позволяют вам обращаться к свойствам, как если бы они былинеобязательный, так что вы можете сделать ваш необязательный параметр свойством (если это еще не сделано, и удалить его из конструктора. Это по-прежнему позволяет писать [Test (null, MyProperty = null)]

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