Можно ли добавить атрибуты во время выполнения или изменить значение атрибута во время выполнения?
Можно ли добавить атрибуты во время выполнения или изменить значение атрибута во время выполнения?
Ответы:
Атрибуты являются статическими метаданными. Сборки, модули, типы, члены, параметры и возвращаемые значения не являются первоклассными объектами в C # (например, System.Type
класс является просто отраженным представлением типа). Вы можете получить экземпляр атрибута для типа и изменить свойства, если они доступны для записи, но это не повлияет на атрибут, поскольку он применяется к типу.
Это действительно зависит от того, что именно вы пытаетесь достичь.
Компонент System.ComponentModel.TypeDescriptor можно использовать для добавления атрибутов к типам, свойствам и экземплярам объектов, и он имеет ограничение, которое необходимо использовать для извлечения этих свойств. Если вы пишете код, который использует эти атрибуты, и вы можете жить в рамках этих ограничений, то я определенно рекомендую это.
Насколько я знаю, элемент управления PropertyGrid и поверхность визуального дизайна студии - единственные вещи в BCL, которые потребляют материал TypeDescriptor. Фактически, именно так они делают примерно половину того, что им действительно нужно делать.
TypeDescriptor
и TypeDescriptionProvider
не реализовано?
[Attr(1), Attr(2), Attr(3)]
только Attr(3)
найден.
Ну, просто чтобы быть другим, я нашел статью, которая ссылается на Reflection.Emit, чтобы сделать это.
Вот ссылка: http://www.codeproject.com/KB/cs/dotnetattributes.aspx , вы также захотите взглянуть на некоторые комментарии в нижней части статьи, потому что обсуждаются возможные подходы.
YourClass
в YourRuntimeClassWithAttributes
.
YourClass
, вы можете создать его подкласс во время выполнения и сгенерировать идентичный класс с немного другим именем, который также имеет нужные динамически созданные атрибуты, и полиморфизм позволит коду проверки типа по-прежнему идентифицировать ваш базовый класс.
Нет, это не так.
Атрибуты являются метаданными и хранятся в двоичной форме в скомпилированной сборке (поэтому вы можете использовать в них только простые типы).
Я не верю в это. Даже если я ошибаюсь, лучшее, на что вы можете надеяться, это добавить их ко всему типу, а не к экземпляру типа.
Если вам нужно что-то, чтобы иметь возможность динамически добавлять атрибуты c #, это не так. Посмотрите на хранение данных в XML. Недавно я сделал проект, который я начал с атрибутов, но в итоге перешел на сериализацию с xml.
Зачем тебе это? Атрибуты дают дополнительную информацию для размышления, но если вы извне знаете, какие свойства вам нужны, они вам не нужны.
Вы можете относительно легко хранить метаданные внешне в базе данных или файле ресурсов.
Я очень старался с System.ComponentModel.TypeDescriptor без успеха. Это не значит, что это не может работать, но я хотел бы увидеть код для этого.
В противоположность, я хотел изменить некоторые значения атрибутов. Я сделал 2 функции, которые отлично работают для этой цели.
// ************************************************************************
public static void SetObjectPropertyDescription(this Type typeOfObject, string propertyName, string description)
{
PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
var att = pd.Attributes[typeof(DescriptionAttribute)] as DescriptionAttribute;
if (att != null)
{
var fieldDescription = att.GetType().GetField("description", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldDescription != null)
{
fieldDescription.SetValue(att, description);
}
}
}
// ************************************************************************
public static void SetPropertyAttributReadOnly(this Type typeOfObject, string propertyName, bool isReadOnly)
{
PropertyDescriptor pd = TypeDescriptor.GetProperties(typeOfObject)[propertyName];
var att = pd.Attributes[typeof(ReadOnlyAttribute)] as ReadOnlyAttribute;
if (att != null)
{
var fieldDescription = att.GetType().GetField("isReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldDescription != null)
{
fieldDescription.SetValue(att, isReadOnly);
}
}
}
В Java я раньше обходил это, используя карту и реализуя свой собственный подход к кодированию значения ключа.
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html
TypeDescriptor
- не толькоPropertyGrid
.