首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否可以在编译时(而不是运行时)在C#中查询自定义属性

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

Stack Overflow用户
提问于 2009-04-15 19:10:17
回答 7查看 8.8K关注 0票数 24

换句话说,如果每个类都没有(“必须有”)自定义属性(例如Author和Version ),那么有可能创建甚至不编译(假设检查代码没有删除)的程序集吗?

以下是我在运行时用于查询的代码:

代码语言:javascript
运行
复制
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 { }

//}

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

然而,问这个问题的原因似乎是weak。也许我应该开始使用一些外部工具,比如:FinalBuilder或创建单元测试来检查这个“需求”,使用Pex、Nunit或其他单元测试框架……

EDIT我在答案的末尾添加了一个控制台程序的小code snippet,用于执行检查...请随时评论、批评或提出改进建议

我再一次意识到这个“需求”应该在“签入”之前作为单元测试的一部分来实现。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-04-15 19:12:58

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

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

当然,您可能仍然应该在代码中验证这一点。您正在尝试做的事情并不能很好地替代正确的运行时检查。

票数 9
EN

Stack Overflow用户

发布于 2009-04-15 19:17:04

您可以运行反映在DLL上的生成后步骤来执行所需的操作。

您必须编写一个命令行应用程序来加载DLL并反映类型。然后,将该命令行应用程序作为构建后步骤运行。我以前也这样做过。如果您了解反射API,这并不是很难做到的。

PostSharp这样做是为了实现面向方面的编程。实际上,这很酷。

票数 4
EN

Stack Overflow用户

发布于 2009-04-15 19:13:56

属性仅在运行时使用。但是:

可以在FXCop (静态分析)中创建一个规则,如果没有定义属性,该规则将失败,并且您的构建/签入过程可能会检查该规则,然后相应地失败。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/753255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档