是否可以在编译期间(而不是运行时)在C#中查询自定义属性

Yor*_*iev 21 c# custom-attributes

换句话说,如果每个类都没有("必须拥有")自定义属性(例如作者和版本),是否可以创建甚至不编译的程序集(假设检查代码未被删除)?

这是我在运行时查询时使用的代码:

using System;
using System.Reflection;
using System.Collections.Generic; 


namespace ForceMetaAttributes
{

    [System.AttributeUsage ( System.AttributeTargets.Method, AllowMultiple = true )]
    class TodoAttribute : System.Attribute
    {
        public TodoAttribute ( string message )
        {
            Message = message;
        }
        public readonly string Message;

    }

    [System.AttributeUsage ( System.AttributeTargets.Class |
        System.AttributeTargets.Struct, AllowMultiple = true )]
    public class AttributeClass : System.Attribute
    {
        public string Description { get; set; }
        public string MusHaveVersion { get; set; }


        public AttributeClass ( string description, string mustHaveVersion ) 
        {
            Description = description; 
            MusHaveVersion = mustHaveVersion ; 
        }

    } //eof class 


    [AttributeClass("AuthorName" , "1.0.0")]
    class ClassToDescribe
    {
        [Todo ( " A todo message " )]
        static void Method ()
        { }
    } //eof class 

    //how to get this one to fail on compile 
    class AnotherClassToDescribe
    { 

    } //eof class 

class QueryApp
{
        public static void Main()
        {

                Type type = typeof(ClassToDescribe);
                AttributeClass objAttributeClass;


                //Querying Class Attributes

                foreach (Attribute attr in type.GetCustomAttributes(true))
                {
                        objAttributeClass = attr as AttributeClass;
                        if (null != objAttributeClass)
                        {
                                Console.WriteLine("Description of AnyClass:\n{0}", 
                                                                    objAttributeClass.Description);
                        }
                }



                //Querying Class-Method Attributes  

                foreach(MethodInfo method in type.GetMethods())
                {
                        foreach (Attribute attr in method.GetCustomAttributes(true))
                        {
                                objAttributeClass = attr as AttributeClass;
                                if (null != objAttributeClass)
                                {
                                        Console.WriteLine("Description of {0}:\n{1}", 
                                                                            method.Name, 
                                                                            objAttributeClass.Description);
                                }
                        }
                }
                //Querying Class-Field (only public) Attributes

                foreach(FieldInfo field in type.GetFields())
                {
                        foreach (Attribute attr in field.GetCustomAttributes(true))
                        {
                                objAttributeClass= attr as AttributeClass;
                                if (null != objAttributeClass)
                                {
                                        Console.WriteLine("Description of {0}:\n{1}",
                                                                            field.Name,objAttributeClass.Description);
                                }
                        }
                }
                Console.WriteLine ( "hit Enter to exit " );
                Console.ReadLine ();
        } //eof Main 
} //eof class 

} //eof namespace 


//uncomment to check whether it works with external namespace 
//namespace TestNamespace {

//  class Class1 { }
//  class Class2 { }

//}
Run Code Online (Sandbox Code Playgroud)

编辑:只是为了证明我的答案选择.我认为casperOne提供了问题的正确答案.

然而,问这个问题的理由似乎很弱.可能我应该开始使用一些外部工具,例如: FinalBuilder 或创建单元测试来检查这个"需求",使用Pex,Nunit或其他单元测试框架......

编辑 我在执行检查的答案的末尾添加了一个控制台程序的小代码片段 ...随意评论,批评或建议改进
再一次我意识到这个"要求"应该作为单元的一部分来实现在"登记入住"之前进行测试

cas*_*One 7

不,不可能挂钩到程序集的编译并检查它是否存在.

但是,您可以挂钩构建过程,该过程不仅仅是运行编译器.您可以创建一个自定义的MSBUILD任务(或NAnt,如果您正在使用它),它在构建后通过反射检查程序集,如果它没有所需的属性,则会使构建失败.

当然,您应该仍然可以在代码中验证这一点.您要做的不是正确运行时检查的良好替代品.