【问题标题】:'constructor' is not a recognized attribute location“构造函数”不是可识别的属性位置
【发布时间】:2020-02-05 22:02:35
【问题描述】:

尝试编译以下代码后:

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

我收到以下错误:

'constructor' 不是可识别的属性位置。此声明的有效属性位置是“方法”。此块中的所有属性都将被忽略。 [Console.NET]csharp(CS0658)

我知道存在以下位置:assemblymodulemethodparameterreturn 等。所以,我的猜测是 constructor 应该作为好吧(因为我们也可以将构造函数作为属性的目标)。但是这里好像不是这样的。

另外,我无法在 MSDN 上找到已识别属性位置的完整列表。因此,如果有人提供指向 MSDN 上位置列表的链接,那将很有帮助。

我对 constructor 位置存在的猜测是基于我在 C# via 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 

输出清楚地表明构造函数的处理方式与类和方法不同。由于有classmethod 位置,我预计constructor 位置也会出现。

我只需要这个来学习。

【问题讨论】:

  • 您能说明一下您想要该代码做什么吗? (显然没有这样的语法......但这使得很难理解你想要实现的目标)。
  • 仅当属性目标不可直接寻址时才需要前缀。该属性已应用于构造函数,因此不需要前缀。
  • @AlexeiLevenkov,我想了解为什么没有像constructor 这样的位置。在问题中,我解释了为什么我期望 constructor 位置存在。谢谢。
  • @qqqqqqq 没有constructor 位置,因为它不需要。在构造函数之前应用属性。
  • @qqqqqqq 可用目标列表在MSDN page on attributes

标签: c# custom-attributes


【解决方案1】:

属性目标列表出现在两个地方:

那么为什么我们有“方法”而不是“构造函数”目标(我的解释,我不知道官方推理):

  • “方法”适用于方法和属性。它包括构造函数作为方法的特殊变体。因此,有一种方法可以允许在构造函数上使用属性,而不是在程序集或字段上使用。
  • 当属性应用于构造函数时,默认“方法”目标没有其他可能的选择,因为构造函数仅匹配目标列表中的“方法”选项(与自动属性不同,例如,属性可以被视为目标)方法”或“属性”甚至“字段”)
  • 大概没有什么有用的情况,属性必须仅限于构造函数。

旁注:因为属性本​​身通常不做任何事情,所以属性目标主要是为了限制设置属性但不影响任何情况的潜在情况。如果你想“定位”只是构造函数,一些好的命名可能就足够了。如果您真的想仅限于构造函数,您可以在启动时检查所有加载的类型是否不当使用您的自定义属性/首先需要检查您的自定义属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多