Раньше я не использовал атрибуты в своей повседневной работе, но я читал о них.
Также я сделал несколько тестов, чтобы подтвердить то, что я скажу здесь. Если я ошибаюсь в любом месте - не стесняйтесь сказать мне это :) 1001 *
Из того, что я знаю, атрибуты не действуют как обычные классы. Они не создаются при создании объекта, к которому они применяются, а не по одному статическому экземпляру, а не по 1 на каждый экземпляр объекта.
Они также не обращаются к классу, к которому они применяются ..
Вместо этого они действуют как свойства (атрибуты?: P) класса. Не так, как класс .NET properties , больше похоже на свойство типа «одно свойство стекла - прозрачность». Вы можете проверить, какие атрибуты применяются к классу из отражения, а затем действовать соответствующим образом. По сути, это метаданные, связанные с определением класса, а не объекты этого типа.
Вы можете попытаться получить список атрибутов для класса, метода, свойства и т. Д. И т. Д. Когда вы получите список этих атрибутов - именно здесь они будут созданы. Затем вы можете воздействовать на данные этих атрибутов.
например. в таблицах Linq свойства имеют атрибуты, определяющие, к какой таблице / столбцу они относятся. Но эти классы не используют эти атрибуты. Вместо этого DataContext проверит атрибуты этих объектов, когда преобразует деревья выражений linq в код SQL.
Теперь о некоторых реальных примерах. Я запустил их в LinqPad , так что не беспокойтесь о странном методе Dump (). Я заменил его на Console.WriteLine, чтобы облегчить понимание кода для людей, которые не знают об этом:)
void Main()
{
Console.WriteLine("before class constructor");
var test = new TestClass();
Console.WriteLine("after class constructor");
var attrs = Attribute.GetCustomAttributes(test.GetType()).Dump();
foreach(var attr in attrs)
if (attr is TestClassAttribute)
Console.WriteLine(attr.ToString());
}
public class TestClassAttribute : Attribute
{
public TestClassAttribute()
{
DefaultDescription = "hello";
Console.WriteLine("I am here. I'm the attribute constructor!");
}
public String CustomDescription {get;set;}
public String DefaultDescription{get;set;}
public override String ToString()
{
return String.Format("Custom: {0}; Default: {1}", CustomDescription, DefaultDescription);
}
}
[Serializable]
[TestClass(CustomDescription="custm")]
public class TestClass
{
public int Foo {get;set;}
}
Результат консоли этого метода:
before class constructor
after class constructor
I am here. I'm the attribute constructor!
Custom: custm; Default: hello
И Attribute.GetCustomAttributes(test.GetType())
возвращает этот массив:
(в таблице показаны все доступные столбцы для всех записей. Нет, атрибут Serializable не имеет этих свойств :))
Есть еще вопросы? Не стесняйтесь спрашивать!
UPD:
Я видел, как вы задаете вопрос: зачем их использовать?
В качестве примера я расскажу вам о библиотеке XML-RPC.NET.
Вы создаете свой класс обслуживания XML-RPC с методами, которые будут представлять методы xml-rpc. Главное сейчас: в XmlRpc имена методов могут иметь некоторые специальные символы, такие как точки. Таким образом, вы можете иметь метод flexlabs.ProcessTask () xml rpc.
Вы определяете этот класс следующим образом:
[XmlRpcMethod("flexlabs.ProcessTask")]
public int ProcessTask_MyCustomName_BecauseILikeIt();
Это позволяет мне называть метод так, как мне нравится, но при этом использовать публичное имя, каким оно и должно быть.