是否可以查询在编译时在C#中的自定义属性(不运行时) [英] Is it possible to query custom Attributes in C# during compile time ( not run-time )

查看:318
本文介绍了是否可以查询在编译时在C#中的自定义属性(不运行时)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在换句话说,它可能是可能创造组装,这甚至不编译(假设检查代码不会被删除)如果类中的每一个没有(必须拥有)的自定义属性(例如作者和?版)



下面是我用来在运行时查询代码:

 使用系统; 
使用的System.Reflection;
使用System.Collections.Generic;


命名空间ForceMetaAttributes
{

[System.AttributeUsage(System.AttributeTargets.Method,的AllowMultiple = TRUE)]
类TodoAttribute: System.Attribute
{
公共TodoAttribute(字符串消息)
{
消息=消息;
}
公共只读字符串消息;

}

[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct,的AllowMultiple = TRUE)]
公共类AttributeClass :System.Attribute
{
公共字符串描述{搞定;组; }
公共字符串MusHaveVersion {搞定;组; }


公共AttributeClass(字符串描述,字符串mustHaveVersion)
{
说明=描述;
MusHaveVersion = mustHaveVersion;
}

} // EOF类


[AttributeClass(AUTHORNAME,1.0.0)]
类ClassToDescribe
{
[藤(A TODO消息)]
静态无效的方法()
{}
} // EOF类

//如何获得这一个失败的编译
类AnotherClassToDescribe
{

} // EOF类

类QueryApp
{
公共静态无效的主要()
{
$ b $型b型= typeof运算(ClassToDescribe);
AttributeClass objAttributeClass;


//查询类属性

的foreach(属性ATTR在type.GetCustomAttributes(真))
{
objAttributeClass =属性为AttributeClass;
如果(空= objAttributeClass!)
{
Console.WriteLine(AnyClass说明:\\\
{0},
objAttributeClass.Description);
}
}



//查询类的方法属性

在type.GetMethods的foreach(MethodInfo的方法( ))
{在method.GetCustomAttributes
的foreach(属性ATTR(真))
{
objAttributeClass =属性为AttributeClass;
如果(空= objAttributeClass!)
{
Console.WriteLine({0}说明:\\\
{1},
method.Name,
objAttributeClass.Description);
}
}
}
//查询类场(仅公用)属性

的foreach(在type.GetFields字段信息字段())
{
的foreach(在field.GetCustomAttributes属性ATTR(真))
{
objAttributeClass =属性为AttributeClass;
如果(空= objAttributeClass!)
{
Console.WriteLine({0}说明:\\\
{1},
field.Name,objAttributeClass.Description );
}
}
}
Console.WriteLine(敲回车退出);
到Console.ReadLine();
} //主EOF
} // EOF类

} // EOF命名空间


//取消注释,以检查它是否与外部空间
//命名空间TestNamespace {

//类class1 {}
//类的Class2 {}

//} $ b工作$ b

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



不过,对于问这个问题的原因似乎是的。也许我应该开始使用一些外部工具,如:
的FinalBuilder
或创建单元测试检查此规定,采用PEX,NUnit的或其他的单元测试框架......



修改
口增加了一个小的代码片段控制台程序在执行检查......随意发表评论,批评或改进建议

一旦答案的结束我越意识到这个规定应实施

解决方案

没有,这是不可能挂接到大会的编制和检查,如果它的存在。



然而的你可以连接到构建过程中,它是由多只运行编译器的更多。您可以创建一个自定义的MSBuild任务(或恶性,如果您正在使用),它通过反射检查组装它建成后,再构建失败,如果它不具备所需的属性。



当然,你应该还是的代码验证这一点。你所要做的是不是一个适当的运行时检查的良好替代品。


In other words could it be possible to create assembly, which does not even compile (assuming the checking code is not removed ) if each one of the Classes does not have ( "must have" ) custom attributes ( for example Author and Version ) ?

Here is the code I have used for querying during run time :

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 { }

//}

Edit: Just to justify my choice for answer. I think casperOne provided the correct answer of the question.

However the reasons for asking the question seemed to be weak. Probably I should start to use some external tool such as : FinalBuilder or create unit tests checking for this "requirement", using Pex , Nunit or other unit testing frameworks ...

EDIT I added a small code snippet of a console program at the end of the answers that performs the check ... feel free to comment, criticize or suggest improvements
Once more I realized that this "requirement" should be implemented

解决方案

No, it is not possible to hook into the compilation of the assembly and check if it exists.

However you can hook into the build process, which is made up of more than just running the compiler. You could create a custom MSBUILD task (or NAnt, if you are using that) which checks the assembly through reflection after it is built and then fail the build if it doesn't have the required attributes.

Of course, you should probably still verify this in code as well. What you are trying to do is not a good substitute for a proper runtime check.

这篇关于是否可以查询在编译时在C#中的自定义属性(不运行时)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆