是否可以在运行时添加属性或在运行时更改属性的值?
答案 0 :(得分:67)
这实际上取决于你想要完成的目标。
System.ComponentModel.TypeDescriptor内容可用于向类型,属性和对象实例添加属性,并且它还有一个限制,即您必须使用它来检索这些属性。如果您正在编写消耗这些属性的代码,并且您可以在这些限制内生存,那么我肯定会建议它。
据我所知,PropertyGrid控件和visual studio设计界面是BCL中唯一使用TypeDescriptor的东西。事实上,这就是他们如何处理他们真正需要做的事情的一半。
答案 1 :(得分:66)
属性是静态元数据。程序集,模块,类型,成员,参数和返回值不是C#中的第一类对象(例如,System.Type
类仅仅是类型的反映表示)。您可以获取类型的属性实例,如果属性可写,则更改属性,但在应用于类型时不会影响属性。
答案 2 :(得分:10)
你做不到。一种解决方法可能是在运行时生成派生类并添加属性,尽管这可能有点过分。
答案 3 :(得分:10)
嗯,只是为了与众不同,我发现了一篇使用Reflection.Emit引用的文章。
以下是链接:http://www.codeproject.com/KB/cs/dotnetattributes.aspx,您还需要查看本文底部的一些评论,因为讨论了可能的方法。
答案 4 :(得分:4)
不,不是。
属性是元数据,并以二进制形式存储在已编译的程序集中(这也是为什么你只能在其中使用简单类型)。
答案 5 :(得分:3)
我不相信。即使我错了,你最希望的是将它们添加到整个类型,而不是类型的实例。
答案 6 :(得分:3)
如果您需要能够动态添加的内容,则不会使用c#属性。考虑将数据存储在xml中。我最近做了一个项目,我开始w /属性,但最终转移到序列化w / xml。
答案 7 :(得分:3)
为什么需要?属性为反射提供了额外的信息,但如果您从外部知道您想要哪些属性,则不需要它们。
您可以相对轻松地在外部将元数据存储在数据库或资源文件中。
答案 8 :(得分:1)
我非常努力地使用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);
}
}
}
答案 9 :(得分:-7)
在Java中,我曾经通过使用地图并实现我自己的键值编码来解决这个问题。
http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/KeyValueCoding.html