Чи можливо додати атрибути під час виконання або змінити значення атрибута під час виконання?
Чи можливо додати атрибути під час виконання або змінити значення атрибута під час виконання?
Відповіді:
Атрибути - це статичні метадані. Асамблеї, модулі, типи, члени, параметри та значення повернення - це не першокласні об'єкти в 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. Нещодавно я зробив проект, у якому я запустив w / атрибути, але врешті-решт перейшов до серіалізації w / 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 я працював над цим, використовуючи карту і реалізуючи власне прийняття кодування Key-Value.
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html
TypeDescriptor
- не тількиPropertyGrid
.