开发者

Understanding TypeDescriptor/PropertyDescriptor/etc

开发者 https://www.devze.com 2023-01-27 20:59 出处:网络
See the code: class DataItem { public DataItem(int num, string s) { Number = num; Str = s; } public int Number { get; set; }

See the code:

class DataItem
{
    public DataItem(int num, string s)
    {
        Number = num;
        Str = s;
    }
    public int Number { get; set; }
    public string Str { get; set; }
}

static void Main(string[] args)
{
    var data = new DataItem(2, "hi");

    var provider = TypeDescriptor.AddAttributes(typeof(DataItem),
                                               new SerializableAttribute());

    var another = provider.CreateInstance(null, typeof(DataItem), 
                                 new Type[] { typeof(int), typeof(string) }, 
                                 new object[] { 100, "hello" }) as DataItem;

    var newProperty = TypeDescriptor.CreateProperty(another.GetType(), "Str", 
                                      typeof(string), 
                                      new DescriptionAttribute("new property"));
    //newProperty.SetValue(another, "new one");

    Console.WriteLine(newProperty.GetValue(another));
开发者_StackOverflow    Console.Read();
}

And I have several questions for the code:

(1) I added a SerializableAttribute to the Type of DataItem, what is this "change" applied to? I can't get this attribute by typeof(DataItem).GetCustomAttributes(true).It seems that the change is not applied to the "essential DataItem", it is stored in the TypeDescriptionProvider temporarily?

(2) The instance another is created by the provider(where we added the attribute), I think now this variable is the same as the one created by the constructor of SerializableAttributed DataItem? even if we can't still get the attribute by another.GetType().GetCustomAttributes.

(3) Another reason I believe the change is temporarily stored in the provider is that I tried to create a property with its name Str and type string, which actually already exists in DataItem. The code will output hello. And if I uncomment the SetValue method, the output will be new one. Do I have any misunderstandings?


The attributes are added to the instance (data) not the type. Have you tried TypeDescriptor.AddAttributes(typeof(DataItem)) instead?


TypeDescriptor, being in System.ComponentModel, is a part of a large but isolated ecosystem of components and related technologies. The purpose of this class is to manipulate design-time (unlike reflection which is compile-time, or run-time DLR) members of a type or instance. This is the case when you create or edit a component in the Visual Studio designer, or in controls like PropertyGrid, where you might need to tweak or customize the properties for easier editing. Similarly, TypeConverter can be used when setting property values in the designer.

While these classes are exteremely useful, it is only in situations where you are working with code that already uses and understands them, therefore...

  1. This change is visible only to code that also uses TypeDescriptor to retrieve the attributes. In my experience, they are not used much in the runtime outside of System.ComponentModel and related namespaces, so specifically your SerializableAttribute example will not actually make the type serializable (it doesn't affect Type.IsSerializable). This may seem limited, but these classes are extremely useful once the whole system uses them (and it is a sort of standard way to extend arbitrary types).

    The change is also permanent, unless you remove the attributes or the associated provider.

  2. The instance is equivalent to the one created before. In addition, both instances have SerializableAttribute, since TypeDescriptor.AddAttributes has global effects.

  3. The confusion is the result of the fact that TypeDescriptor.CreateProperty does not actually create a property, merely a property descriptor from an existing property. Accesing it through the descriptor will simply modify the real property of the object.

All in all, TypeDescriptor is used to describe a new system (components) using standard language (types, properties, events, attributes), but they are otherwise unrelated.

0

精彩评论

暂无评论...
验证码 换一张
取 消