Сокращение имени атрибута C #

20

Как возможно, что атрибуты C # имеют атрибут «Атрибут» в имени (например, DataMemberAttribute ), но инициализируются без этого суффикса? например:.

[DataMember]
private int i;
    
задан Fabiano 27.01.2010 в 11:03
источник
  • Я бы заметил, что вопрос КАК это возможно, пока не ответил. но я считаю, что он ищет с использованием отражения X ИЛИ X + «Атрибут» для имен. –  serhio 27.01.2010 в 11:22
  • @serhio в соответствии с Антоном Гоголевым - это ярлык, предоставленный компилятором. Этого достаточно для меня в качестве ответа (если это правильно). И он также работает с пользовательскими атрибутами. –  Fabiano 27.01.2010 в 11:30
  • Лично для меня не совсем понятно, какой «ярлык» может предоставить компилятор. –  serhio 27.01.2010 в 12:13
  • @serhio - возможно, меньше названия для переноса? Это кажется немного непоследовательным (компилятор удаляет «класс» из суффикса имени класса?), Но по крайней мере это имеет смысл. –  StingyJack 03.01.2012 в 16:33

3 ответа

20

В соответствии с спецификацией языка C # ,

  

По соглашению классы атрибутов называются суффикс Attribute . имя-атрибут формы имя-типа может включать или опускать этот суффикс.

Это ярлык, предоставляемый компилятором C # и никоим образом не CLR-функцией. Другим примером специальной обработки атрибутов компилятором является атрибут ObsoleteAttribute : он заставляет a компилятор , чтобы выпустить предупреждение / ошибку, но это не имеет особого значения для CLR.

Что касается определения атрибутов, см. ссылку выше. Подводя итог:

  

Если класс атрибута найден как с суффиксом, так и без него, возникает неоднозначность и возникает ошибка времени компиляции. Если attribute-name написано так, что его самый правый идентификатор является дословным идентификатором , тогда сопоставляется только атрибут без суффикса, что позволяет разрешить такую неоднозначность.

A "verbatim identifier" - это идентификатор с префиксом @ .

Продолжение работы с MSDN:

using System;

[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}

[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}

[X]                  // Error: ambiguity
class Class1 {}

[XAttribute]         // Refers to XAttribute
class Class2 {}

[@X]                  // Refers to X
class Class3 {}

[@XAttribute]         // Refers to XAttribute
class Class4 {}
  

Атрибут [X] неоднозначен, так как он может ссылаться либо на X , либо XAttribute . Использование дословного идентификатора позволяет точно указать намерение в таких редких случаях. Атрибут [XAttribute] не является двусмысленным (хотя это было бы, если бы был класс атрибута с именем XAttributeAttribute !). Если объявление класса X удалено, то оба атрибута относятся к классу атрибутов с именем XAttribute , как показано ниже:

using System;
[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}

[X]                  // Refers to XAttribute
class Class1 {}

[XAttribute]         // Refers to XAttribute
class Class2 {}

[@X]                  // Error: no attribute named "X"
class Class3 {}
    
ответ дан Anton Gogolev 27.01.2010 в 11:08
7

Это одно и то же. [XAttribute] == [X]

из MSDN :

  

По соглашению все имена атрибутов заканчиваются   со словом « Атрибут ", чтобы   отличать их от других предметов в   .NET Framework. Однако вы делаете   не нужно указывать атрибут   суффикс при использовании атрибутов в коде.   Например, [DllImport] эквивалентно   до [DllImportAttribute] , но DllImportAttribute - это атрибут   фактическое имя в .NET Framework.

, мы также можем прочитать:

  

Если класс атрибута найден как   с и без этого суффикса,   существует двусмысленность, и   результаты ошибки компиляции. Если   имя атрибута написано так, что   его самый правый идентификатор   verbatim identifier, то только атрибут без   суффикс, что позволяет   неопределенность, которую нужно решить:

using System;

[AttributeUsage(AttributeTargets.All)]
public class X: Attribute
{}
[AttributeUsage(AttributeTargets.All)]
public class XAttribute: Attribute
{}
[X]                  // Error: ambiguity
class Class1 {}
[XAttribute]         // Refers to XAttribute
class Class2 {}
[@X]                  // Refers to X
class Class3 {}
[@XAttribute]         // Refers to XAttribute
class Class4 {}
    
ответ дан serhio 27.01.2010 в 11:06
3

Это соглашение в C # -компиляторе. Как и на странице MSDN на странице «Использование атрибутов» :

  

По соглашению все имена атрибутов заканчиваются   со словом «Атрибут»   отличать их от других предметов в   .NET Framework. Однако вы делаете   не нужно указывать атрибут   суффикс при использовании атрибутов в коде.   Например, [DllImport ] эквивалентен   на [DllImportAttribute] , но    DllImportAttribute - это атрибут   фактическое имя в .NET Framework.

Он работает таким же образом в VB.NET .

    
ответ дан Seb Nilsson 27.01.2010 в 11:10
  • Вы сказали, что это соглашение в .NET Framework, так почему вы должны различать C # и VB.NET? –  serhio 27.01.2010 в 12:10