'конструктор' не является распознанным атрибутом местоположения - PullRequest
0 голосов
/ 06 февраля 2020

После попытки скомпилировать следующий код:

public sealed class Program
{
    [constructor: CLSCompliant(false)]
    public Program()
    {
    }
}

Я получаю следующую ошибку:

'конструктор' не является распознанным расположением атрибута. Допустимые местоположения атрибута для этого объявления - «метод». Все атрибуты в этом блоке будут игнорироваться. [Console.NET] csharp (CS0658)

Я знаю, что присутствуют следующие местоположения: assembly, module, method, parameter, return и др. c. Итак, я предположил, что constructor также должен присутствовать (поскольку мы можем иметь конструктор в качестве цели для атрибута). Но, похоже, это не тот случай.

Кроме того, мне не удалось найти полный список распознанных атрибутов в MSDN. Итак, было бы полезно, если бы кто-то предоставил ссылку на список местоположений в MSDN.

Мои предположения о наличии местоположения constructor основывались после того, как я встретил следующий пример кода в C# через CLR книга:

using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
[assembly: CLSCompliant(true)]
[Serializable]
[DefaultMemberAttribute("Main")]
[DebuggerDisplayAttribute("Richter", Name = "Jeff", Target = typeof(Program))]
public sealed class Program
{
    [Conditional("Debug")]
    [Conditional("Release")]
    public void DoSomething() { }
    public Program()
    {
    }
    [CLSCompliant(true)]
    [STAThread]
    public static void Main()
    {
        // Show the set of attributes applied to this type
        ShowAttributes(typeof(Program));
        // Get the set of methods associated with the type
        var members =
        from m in typeof(Program).GetTypeInfo().DeclaredMembers.OfType<MethodBase>()
        where m.IsPublic
        select m;
        foreach (MemberInfo member in members)
        {
            // Show the set of attributes applied to this member
            ShowAttributes(member);
        }
    }
    private static void ShowAttributes(MemberInfo attributeTarget)
    {
        var attributes = attributeTarget.GetCustomAttributes<Attribute>();

        Console.WriteLine("Attributes applied to {0}: {1}",
        attributeTarget.Name, (attributes.Count() == 0 ? "None" : String.Empty));
        foreach (Attribute attribute in attributes)
        {
            // Display the type of each applied attribute
            Console.WriteLine(" {0}", attribute.GetType().ToString());

            if (attribute is DefaultMemberAttribute)
                Console.WriteLine(" MemberName={0}",
                ((DefaultMemberAttribute)attribute).MemberName);
            if (attribute is ConditionalAttribute)
                Console.WriteLine(" ConditionString={0}",
                ((ConditionalAttribute)attribute).ConditionString);
            if (attribute is CLSCompliantAttribute)
                Console.WriteLine(" IsCompliant={0}",
                ((CLSCompliantAttribute)attribute).IsCompliant);
            DebuggerDisplayAttribute dda = attribute as DebuggerDisplayAttribute;
            if (dda != null)
            {
            Console.WriteLine(" Value={0}, Name={1}, Target={2}",
 dda.Value, dda.Name, dda.Target);
            }
        }
        Console.WriteLine();
    }
}

И вывод этой программы следующий:

Attributes applied to Program:
 System.SerializableAttribute
 System.Diagnostics.DebuggerDisplayAttribute
 Value=Richter, Name=Jeff, Target=Program
 System.Reflection.DefaultMemberAttribute
 MemberName=Main

Attributes applied to DoSomething:
 System.Diagnostics.ConditionalAttribute
 ConditionString=Release
 System.Diagnostics.ConditionalAttribute
 ConditionString=Debug

Attributes applied to Main:
 System.CLSCompliantAttribute
 IsCompliant=True
 System.STAThreadAttribute

Attributes applied to .ctor: None 

Вывод проясняет, что конструктор относиться по-разному от класса и метода. И поскольку есть местоположения class и method, я ожидаю, что я также буду присутствовать в расположении constructor.

Мне это нужно исключительно для целей обучения.

1 Ответ

1 голос
/ 06 февраля 2020

Список целей атрибутов представлен в двух местах:

  • ограничивает область применения атрибута (через AttributeUsageAttribute )
  • устраняет неоднозначность, к чему применяется атрибут в каждом конкретном случае (через «Атрибуты целей» )

Так почему у нас были бы «метод», а не «конструктор» целей (моя интерпретация, я не знаю официального рассуждения):

  • «метод» применяется к методам и свойствам. Он включает конструктор как особый вариант метода. Таким образом, есть способ разрешить использование атрибута в конструкторе, а не в сборке или поле.
  • когда атрибут применяется к конструктору, нет другого возможного выбора для цели по умолчанию "method" как конструктор совпадает только с опцией «method» из списка целей (в отличие от auto-свойства, например, когда атрибут может рассматриваться как нацеливающий «method» или «property» или даже «field»)
  • предположительно, нет никакой полезной случай, когда атрибут должен быть ограничен только конструкторами.

Примечание: поскольку сами атрибуты вообще ничего не делают, цели атрибутов в основном ограничивают потенциальные случаи, когда атрибут установлен, но ничего не влияет. Если вы хотите «нацеливаться» только на конструкторов, может быть достаточно хорошего именования. Если вы действительно хотите ограничиться только конструкторами, вы можете проверить все загруженные типы на предмет неправильного использования вашего пользовательского атрибута при запуске / сначала нужно проверить свой пользовательский атрибут.

...