理解类型描述符/属性描述符等

发布于 10-04 20:05 字数 1598 浏览 12 评论 0原文

查看代码:

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));
    Console.Read();
}

并且我对代码有几个问题:

(1)我在DataItem的Type中添加了一个SerializedAttribute,这个“更改”应用于什么?我无法通过typeof(DataItem).GetCustomAttributes(true)获取此属性。看来更改并未应用于“基本DataItem”,它暂时存储在TypeDescriptionProvider中?

(2) 实例 another 是由提供者创建的(我们添加属性的地方),我想现在这个变量与 SerializedAttributed DataItem 的构造函数创建的变量相同?即使我们仍然无法通过 another.GetType().GetCustomAttributes 获取属性。

(3) 我认为更改暂时存储在提供程序中的另一个原因是我尝试创建一个名为 Str 和类型 string 的属性,该属性实际上已经存在于数据项。该代码将输出 hello。如果我取消注释 SetValue 方法,输出将为 new one。我是不是有什么误解?

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));
    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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

如此安好2024-10-11 20:05:08

TypeDescriptor 位于 System.ComponentModel 中,是一个庞大但孤立的组件和相关技术生态系统的一部分。此类的目的是操作类型或实例的设计时(与编译时或运行时DLR 反射不同)成员。当您在 Visual Studio 设计器中或在 PropertyGrid,您可能需要在其中调整或自定义属性以便于编辑。
同样,TypeConverter在设计器中设置属性值时可以使用。

虽然这些类非常有用,但仅在您正在使用已经使用并理解它们的代码的情况下,因此...

  1. 此更改仅对也使用 TypeDescriptor 的代码可见检索属性。根据我的经验,它们在 System.ComponentModel 和相关命名空间之外的运行时中使用不多,因此具体而言,您的 SerializedAttribute 示例实际上不会使类型可序列化(它不会不影响Type.IsSerialized)。这可能看起来很有限,但是一旦整个系统使用这些类,它们就非常有用(并且它是扩展任意类型的一种标准方法)。

    除非您删除属性或关联的提供程序,否则更改也是永久性的。

  2. 该实例与之前创建的实例等效。此外,两个实例都具有SerializedAttribute,因为TypeDescriptor.AddAttributes具有全局效果。

  3. 造成混乱的原因是 TypeDescriptor.CreateProperty 实际上并没有创建属性,而只是从现有属性创建属性描述符。通过描述符访问它只会修改对象的真实属性。

总而言之,TypeDescriptor 用于使用标准语言(类型、属性、事件、属性)描述系统(组件),但它们在其他方面是不相关的。

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.

甜警司2024-10-11 20:05:08

属性被添加到实例(数据)而不是类型。您是否尝试过 TypeDescriptor.AddAttributes(typeof(DataItem)) ?

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文