gpt4 book ai didi

c# - 在运行时添加属性

转载 作者:可可西里 更新时间:2023-11-01 07:45:43 25 4
gpt4 key购买 nike

我有一个程序员可以用来动态添加新属性的类。为此,它实现了 ICustomTypeDescriptor 以能够覆盖 GetProperties() 方法。

public class DynamicProperty
{
public object Value { get; set; }

public Type Type { get; set; }

public string Name { get; set; }

public Collection<Attribute> Attributes { get; set; }
}

public class DynamicClass : ICustomTypeDescriptor
{
// Collection to code add dynamic properties
public KeyedCollection<string, DynamicProperty> Properties
{
get;
private set;
}

// ICustomTypeDescriptor implementation
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
{
// Properties founded within instance
PropertyInfo[] instanceProps = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

// Fill property collection with founded properties
PropertyDescriptorCollection propsCollection =
new PropertyDescriptorCollection(instanceProps.Cast<PropertyDescriptor>().ToArray());

// Fill property collection with dynamic properties (Properties)
foreach (var prop in Properties)
{
// HOW TO?
}

return propsCollection;
}
}

是否可以迭代属性列表以将每个属性添加到 PropertyDescriptorCollection

基本上,我希望程序员能够将 DynamicProperty 添加到将由 GetProperties 处理的集合中。像这样的东西:

new DynamicClass()
{
Properties = {
new DynamicProperty() {
Name = "StringProp",
Type = System.String,
Value = "My string here"
},

new DynamicProperty() {
Name = "IntProp",
Type = System.Int32,
Value = 10
}
}
}

现在,每当调用 GetProperties 时,这些 Properties 将被设置为实例属性。我的想法是否正确?

最佳答案

您已经像这样创建了一个集合:

PropertyDescriptorCollection propsCollection = 
new PropertyDescriptorCollection(instanceProps.Cast<PropertyDescriptor>().ToArray());

但是您正在创建的集合只有现有属性,没有您的新属性。

您需要提供一个由现有属性和新属性串联而成的数组。

像这样:

instanceProps.Cast<PropertyDescriptor>().Concat(customProperties).ToArray()

下一个问题:您需要 customProperties,它是 PropertyDescriptor 的集合。不幸的是,PropertyDescriptor 是一个抽象类,因此您没有一种简单的方法来创建它。

不过,我们可以解决这个问题,只需通过从 PropertyDescriptor 派生并实现所有抽象方法来定义您自己的 CustomPropertyDescriptor 类。

像这样:

public class CustomPropertyDescriptor : PropertyDescriptor
{
private Type propertyType;
private Type componentType;

public CustomPropertyDescriptor(string propertyName, Type propertyType, Type componentType)
: base(propertyName, new Attribute[] { })
{
this.propertyType = propertyType;
this.componentType = componentType;
}

public override bool CanResetValue(object component) { return true; }
public override Type ComponentType { get { return componentType; } }
public override object GetValue(object component) { return 0; /* your code here to get a value */; }
public override bool IsReadOnly { get { return false; } }
public override Type PropertyType { get { return propertyType; } }
public override void ResetValue(object component) { SetValue(component, null); }
public override void SetValue(object component, object value) { /* your code here to set a value */; }
public override bool ShouldSerializeValue(object component) { return true; }
}

我还没有填写获取和设置属性的调用;这些调用取决于您如何在幕后实现动态属性。

然后您需要创建一个 CustomPropertyDescriptor 数组,其中填充了适合您的动态属性的信息,并将其连接到我最初描述的基本属性。

PropertyDescriptor 不仅描述您的属性,它还使客户端能够实际获取和设置这些属性的值。这就是重点,不是吗!

关于c# - 在运行时添加属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6166236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com