8,833
社区成员




public class ClassBuilder {
AssemblyName assemblyName;
public ClassBuilder(string className) {
this.assemblyName = new AssemblyName(className);
}
public object CreateObject(string[] propertyNames, Type[] types) {
if (propertyNames.Length != types.Length) {
System.Windows.Forms.MessageBox.Show("属性名数量和类型数量不匹配.");
}
TypeBuilder DynamicClass = this.CreateClass();
this.CreateConstructor(DynamicClass);
for (int i = 0; i < propertyNames.Length; i++) {
CreateProperty(DynamicClass, propertyNames[i], types[i]);
}
Type type = DynamicClass.CreateType();
return Activator.CreateInstance(type);
}
private void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propertyType) {
FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
MethodBuilder setPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyType });
ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
private void CreateConstructor(TypeBuilder typeBuilder) {
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
}
private TypeBuilder CreateClass() {
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(this.assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType(this.assemblyName.FullName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null);
return typeBuilder;
}
}
public override string ToString() {
return base.ToString() + " (" + Component + ")";
}
public DynamicTypeDescriptor FromComponent(object component) {
if (component == null) {
throw new ArgumentNullException("component");
}
if (!_type.IsAssignableFrom(component.GetType())) {
throw new ArgumentException(null, "component");
}
DynamicTypeDescriptor desc = new DynamicTypeDescriptor();
desc._type = _type;
desc.Component = component;
desc._typeConverter = _typeConverter;
desc._editors = _editors;
desc._defaultEvent = _defaultEvent;
desc._defaultProperty = _defaultProperty;
desc._attributes = _attributes;
desc._events = _events;
desc.OriginalProperties = OriginalProperties;
List<PropertyDescriptor> properties = new List<PropertyDescriptor>();
foreach (PropertyDescriptor pd in Properties) {
DynamicProperty dp = new DynamicProperty(desc, pd, component);
properties.Add(dp);
}
desc.Properties = new PropertyDescriptorCollection(properties.ToArray());
return desc;
}
public object Component { get; private set; }
public string ClassName { get; set; }
public string ComponentName { get; set; }
public AttributeCollection GetAttributes() {
return _attributes;
}
public string GetClassName() {
if (ClassName != null) {
return ClassName;
}
if (Component != null) {
return Component.GetType().Name;
}
if (_type != null) {
return _type.Name;
}
return null;
}
public string GetComponentName() {
if (ComponentName != null) {
return ComponentName;
}
return Component != null ? Component.ToString() : null;
}
public TypeConverter GetConverter() {
return _typeConverter;
}
public EventDescriptor GetDefaultEvent() {
return _defaultEvent;
}
public PropertyDescriptor GetDefaultProperty() {
return _defaultProperty;
}
public EventDescriptorCollection GetEvents() {
return _events;
}
public EventDescriptorCollection GetEvents(Attribute[] attributes) {
return _events;
}
public PropertyDescriptorCollection GetProperties() {
return Properties;
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
return Properties;
}
public object GetPropertyOwner(PropertyDescriptor pd) {
return Component;
}
public object GetEditor(Type editorBaseType) {
object editor;
if (_editors.TryGetValue(editorBaseType, out editor)) {
return editor;
}
return null;
}
}
public override Type PropertyType {
get {
if (_existing != null) {
return _existing.PropertyType;
}
return _type;
}
}
public override void ResetValue(object component) {
if (_existing != null) {
_existing.ResetValue(component);
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(Name));
}
_descriptor.OnValueChanged(this);
return;
}
if (CanResetValue(component)) {
Value = _defaultValue;
_descriptor.OnValueChanged(this);
}
}
public override void SetValue(object component, object value) {
if (_existing != null) {
_existing.SetValue(component, value);
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(Name));
}
_descriptor.OnValueChanged(this);
return;
}
Value = value;
_descriptor.OnValueChanged(this);
}
public override bool ShouldSerializeValue(object component) {
if (_existing != null) {
return _existing.ShouldSerializeValue(component);
}
return false;
}
public override object GetEditor(Type editorBaseType) {
if (editorBaseType == null) {
throw new ArgumentNullException("editorBaseType");
}
if (_editors != null) {
object type;
if ((_editors.TryGetValue(editorBaseType, out type)) && (type != null)) {
return type;
}
}
return base.GetEditor(editorBaseType);
}
public void SetEditor(Type editorBaseType, object obj) {
if (editorBaseType == null) {
throw new ArgumentNullException("editorBaseType");
}
if (_editors == null) {
if (obj == null) {
return;
}
_editors = new Dictionary<Type, object>();
}
if (obj == null) {
_editors.Remove(editorBaseType);
} else {
_editors[editorBaseType] = obj;
}
}
}
public PropertyDescriptor AddProperty(Type type, string name, object value, string displayName, string description, string category, bool hasDefaultValue, object defaultValue, bool readOnly) {
return AddProperty(type, name, value, displayName, description, category, hasDefaultValue, defaultValue, readOnly, null);
}
public PropertyDescriptor AddProperty(Type type, string name, object value, string displayName, string description, string category, bool hasDefaultValue, object defaultValue, bool readOnly, Type uiTypeEditor) {
if (type == null) {
throw new ArgumentNullException("type");
}
if (name == null) {
throw new ArgumentNullException("name");
}
List<Attribute> atts = new List<Attribute>();
if (!string.IsNullOrEmpty(displayName)) {
atts.Add(new DisplayNameAttribute(displayName));
}
if (!string.IsNullOrEmpty(description)) {
atts.Add(new DescriptionAttribute(description));
}
if (!string.IsNullOrEmpty(category)) {
atts.Add(new CategoryAttribute(category));
}
if (hasDefaultValue) {
atts.Add(new DefaultValueAttribute(defaultValue));
}
if (uiTypeEditor != null) {
atts.Add(new EditorAttribute(uiTypeEditor, typeof(UITypeEditor)));
}
if (readOnly) {
atts.Add(new ReadOnlyAttribute(true));
}
DynamicProperty property = new DynamicProperty(this, type, value, name, atts.ToArray());
AddProperty(property);
return property;
}
public void AddProperty(PropertyDescriptor property) {
if (property == null) {
throw new ArgumentNullException("property");
}
Properties.Add(property);
}
public void RemoveProperty(string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
List<PropertyDescriptor> remove = new List<PropertyDescriptor>();
foreach (PropertyDescriptor pd in Properties) {
if (pd.Name == name) {
remove.Add(pd);
}
}
foreach (PropertyDescriptor pd in remove) {
Properties.Remove(pd);
}
}
public sealed class DynamicTypeDescriptor : ICustomTypeDescriptor, INotifyPropertyChanged {
private Type _type;
private AttributeCollection _attributes;
private TypeConverter _typeConverter;
private Dictionary<Type, object> _editors;
private EventDescriptor _defaultEvent;
private PropertyDescriptor _defaultProperty;
private EventDescriptorCollection _events;
public PropertyDescriptorCollection OriginalProperties { get; private set; }
public PropertyDescriptorCollection Properties { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
private DynamicTypeDescriptor() {
}
public DynamicTypeDescriptor(Type type) {
if (type == null) {
throw new ArgumentNullException("type");
}
_type = type;
_typeConverter = TypeDescriptor.GetConverter(type);
_defaultEvent = TypeDescriptor.GetDefaultEvent(type);
_defaultProperty = TypeDescriptor.GetDefaultProperty(type);
_events = TypeDescriptor.GetEvents(type);
List<PropertyDescriptor> normalProperties = new List<PropertyDescriptor>();
OriginalProperties = TypeDescriptor.GetProperties(type);
foreach (PropertyDescriptor property in OriginalProperties) {
if (!property.IsBrowsable) {
continue;
}
normalProperties.Add(property);
}
Properties = new PropertyDescriptorCollection(normalProperties.ToArray());
_attributes = TypeDescriptor.GetAttributes(type);
_editors = new Dictionary<Type, object>();
object editor = TypeDescriptor.GetEditor(type, typeof(UITypeEditor));
if (editor != null) {
_editors.Add(typeof(UITypeEditor), editor);
}
editor = TypeDescriptor.GetEditor(type, typeof(ComponentEditor));
if (editor != null) {
_editors.Add(typeof(ComponentEditor), editor);
}
editor = TypeDescriptor.GetEditor(type, typeof(InstanceCreationEditor));
if (editor != null) {
_editors.Add(typeof(InstanceCreationEditor), editor);
}
}
public T GetPropertyValue<T>(string name, T defaultValue) {
if (name == null) {
throw new ArgumentNullException("name");
}
foreach (PropertyDescriptor pd in Properties) {
if (pd.Name == name) {
try {
return (T)Convert.ChangeType(pd.GetValue(Component), typeof(T));
} catch {
return defaultValue;
}
}
}
return defaultValue;
}
public void SetPropertyValue(string name, object value) {
if (name == null) {
throw new ArgumentNullException("name");
}
foreach (PropertyDescriptor pd in Properties) {
if (pd.Name == name) {
pd.SetValue(Component, value);
break;
}
}
}
internal void OnValueChanged(PropertyDescriptor prop) {
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) {
handler(this, new PropertyChangedEventArgs(prop.Name));
}
}
internal static T GetAttribute<T>(AttributeCollection attributes) where T : Attribute {
if (attributes == null) {
return null;
}
foreach (Attribute attribute in attributes) {
if (typeof(T).IsAssignableFrom(attribute.GetType())) {
return (T)attribute;
}
}
return null;
}
public sealed class DynamicProperty : PropertyDescriptor, INotifyPropertyChanged {
private readonly Type _type;
private readonly bool _hasDefaultValue;
private readonly object _defaultValue;
private readonly PropertyDescriptor _existing;
private readonly DynamicTypeDescriptor _descriptor;
private Dictionary<Type, object> _editors;
private bool? _readOnly;
private bool? _browsable;
private string _displayName;
private string _description;
private string _category;
private List<Attribute> _attributes = new List<Attribute>();
public event PropertyChangedEventHandler PropertyChanged;
internal DynamicProperty(DynamicTypeDescriptor descriptor, Type type, object value, string name, Attribute[] attrs) : base(name, attrs) {
_descriptor = descriptor;
_type = type;
Value = value;
DefaultValueAttribute def = DynamicTypeDescriptor.GetAttribute<DefaultValueAttribute>(Attributes);
if (def == null) {
_hasDefaultValue = false;
} else {
_hasDefaultValue = true;
_defaultValue = def.Value;
}
if (attrs != null) {
foreach (Attribute att in attrs) {
_attributes.Add(att);
}
}
}
internal static Attribute[] GetAttributes(PropertyDescriptor existing) {
List<Attribute> atts = new List<Attribute>();
foreach (Attribute a in existing.Attributes) {
atts.Add(a);
}
return atts.ToArray();
}
internal DynamicProperty(DynamicTypeDescriptor descriptor, PropertyDescriptor existing, object component) : this(descriptor, existing.PropertyType, existing.GetValue(component), existing.Name, GetAttributes(existing)) {
_existing = existing;
}
public void RemoveAttributesOfType<T>() where T : Attribute {
List<Attribute> remove = new List<Attribute>();
foreach (Attribute attribute in _attributes) {
if (typeof(T).IsAssignableFrom(attribute.GetType())) {
remove.Add(attribute);
}
}
foreach (Attribute attribute in remove) {
_attributes.Remove(attribute);
}
}
public IList<Attribute> AttributesList {
get {
return _attributes;
}
}
public override AttributeCollection Attributes {
get {
return new AttributeCollection(_attributes.ToArray());
}
}
public object Value { get; set; }
public override bool CanResetValue(object component) {
if (_existing != null) {
return _existing.CanResetValue(component);
}
return _hasDefaultValue;
}
public override Type ComponentType {
get {
if (_existing != null) {
return _existing.ComponentType;
}
return typeof(object);
}
}
public override object GetValue(object component) {
if (_existing != null) {
return _existing.GetValue(component);
}
return Value;
}
public override string Category {
get {
if (_category != null) {
return _category;
}
return base.Category;
}
}
public void SetCategory(string category) {
_category = category;
}
public override string Description {
get {
if (_description != null) {
return _description;
}
return base.Description;
}
}
public void SetDescription(string description) {
_description = description;
}
public override string DisplayName {
get {
if (_displayName != null) {
return _displayName;
}
if (_existing != null) {
return _existing.DisplayName;
}
return base.DisplayName;
}
}
public void SetDisplayName(string displayName) {
_displayName = displayName;
}
public override bool IsBrowsable {
get {
if (_browsable.HasValue) {
return _browsable.Value;
}
return base.IsBrowsable;
}
}
public void SetBrowsable(bool browsable) {
_browsable = browsable;
}
public override bool IsReadOnly {
get {
if (_readOnly.HasValue) {
return _readOnly.Value;
}
if (_existing != null) {
return _existing.IsReadOnly;
}
ReadOnlyAttribute att = DynamicTypeDescriptor.GetAttribute<ReadOnlyAttribute>(Attributes);
if (att == null) {
return false;
}
return att.IsReadOnly;
}
}
public static class PropertyDescriptorExtensions {
public static void SetReadOnlyAttribute(this PropertyDescriptor p, bool value) {
var attributes = p.Attributes.Cast<Attribute>().Where(x => !(x is ReadOnlyAttribute)).ToList();
attributes.Add(new ReadOnlyAttribute(value));
typeof(MemberDescriptor).GetProperty("AttributeArray", BindingFlags.Instance | BindingFlags.NonPublic).SetValue((MemberDescriptor)p, attributes.ToArray());
}
public static void SetExpandableAttribute(this PropertyDescriptor p, bool value) {
var attributes = p.Attributes.Cast<Attribute>().Where(x => (x is ReadOnlyAttribute)).ToList();
if (value) {
attributes.Add(new TypeConverterAttribute(typeof(ExpandableObjectConverter)));
}
typeof(MemberDescriptor).GetProperty("AttributeArray", BindingFlags.Instance | BindingFlags.NonPublic).SetValue((MemberDescriptor)p, attributes.ToArray());
}
}
然后调用的code如下:
try {
string configInfo = string.Empty;
ReadConfigInfo(out configInfo);
var configObject = JsonConvert.DeserializeObject<JObject>(configInfo);
var obj = CreateClass("config", configObject);
var customClass = JsonConvert.DeserializeObject(configInfo, obj.GetType());
var customClassType = customClass.GetType();
DynamicTypeDescriptor typeDescriptor = new DynamicTypeDescriptor(customClassType);
var propertyDescriptorList = typeDescriptor.Properties.Cast<PropertyDescriptor>().ToList().Where(p => p.PropertyType.Name != "String").ToList();
PropExpandAndReadOnly(propertyDescriptorList);
m_config = typeDescriptor.FromComponent(customClass);
propertyGrid1.SelectedObject = m_config;
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
}