Другими словами можно создать сборку, которая даже не компилируется (при условии, что код проверки не удаляется), если каждый из них классы не имеют (должны иметь) настраиваемые атрибуты (например, Author и Version)?Возможно ли запросить пользовательские атрибуты в C# во время компиляции (не время выполнения)
Вот код, который я использовал для запроса во время выполнения:
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: Просто чтобы оправдать свой выбор для ответа. Я думаю, что casperOne предоставил правильный ответ на вопрос.
Однако причины для запроса вопроса были weak. Возможно, я должен начать использовать некоторые внешние средства, такие как: FinalBuilder или создавать модульные тесты, проверяя для этого «требования», используя PEX, NUnit или другие структуры модульного тестирования ...
EDIT Я добавил небольшой code snippet консольной программы в конце ответов, которые выполняют проверку ... не стесняйтесь комментировать, критиковать или предлагать улучшения
Еще раз я понял, что это «требование» должно быть реализовано как часть модульного тестирования непосредственно перед «регистрация»
Thaks для ответа на! Что вы имеете в виду более конкретно: «То, что вы пытаетесь сделать, не является хорошей заменой для правильной проверки времени выполнения»? –
@YordanGeorgiev: Даже если у вас есть процесс сборки, который гарантирует, что атрибут применяется, вы должны STILL проверить свой код во время выполнения, чтобы убедиться, что этот атрибут применяется. Вы не можете остановить проверку там, потому что думаете, что поймали ее во время компиляции. – casperOne
Таким образом, требование получения атрибутов не менее 4 "должно иметь" повлияет на производительность, из-за отражения ... Кажется, что выполнение проверок в модульных тестах будет чем лучшая идея?! –