有关使用反射来动态生成类一个继承与StringConverter类的问题
我使用propertygrid控件来显示多值的属性,即在其中以combobox显示信息,所以会使用类适于[TypeConverter(typeof(Wage))]的语句加在指定的属性上面。但是像这样包含上面语句的类是动态生成的,即用System.Reflection.emt中的类来生成的,所以我使用属性的方法
Type multiConverter = DynamicMulitClassAnalyzer.m_instance.CreateMultiType(multiValuePropertysc.m_sProperyName, multiValuePropertysc.m_value);
ci = typeof(TypeConverterAttribute).GetConstructor(new Type[]{ typeof(Type) });
CustomAttributeBuilder typeConvertAttrBuilder = new CustomAttributeBuilder(ci,
new object[] { multiConverter });
propertyBuilder.SetCustomAttribute(typeConvertAttrBuilder);
而那个继承StringConverter的那个动态生成的类的生成方法,我写成下面这样:
internal class DynamicMulitClassAnalyzer
{
public static readonly DynamicMulitClassAnalyzer m_instance = new DynamicMulitClassAnalyzer();
private ArrayList m_valueArray = null;
private DynamicMulitClassAnalyzer()
{
}
public Type CreateMultiType(string sPropertyName, ArrayList valueArray)
{
m_valueArray = valueArray;
AppDomain appDomain = Thread.GetDomain(); //得到当前的应用程序域
AssemblyName asmName = this.GetType().Assembly.GetName();
AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule("XBasis");
string sClassName = string.Format("Multi{0}", sPropertyName);
TypeBuilder typeBuilder = moduleBuilder.DefineType(sClassName,
TypeAttributes.Class | TypeAttributes.Public,
typeof(StringConverter));
AddMethodImp(typeBuilder, "GetStandardValuesSupported", new GenerateCodeOp(GetStandardValuesSupportedImp));
// AddMethodImp(typeBuilder, "GetStandardValuesExclusive", new GenerateCodeOp(GetStandardValuesExclusiveImp));
// AddMethodImp(typeBuilder, "GetStandardValues", new GenerateCodeOp(GetStandardValuesImp));
return typeBuilder.CreateType();
}
private void AddMethodImp(TypeBuilder typeBuilder, string sOverideMethodName, GenerateCodeOp gcOP)
{
MethodInfo MethodDl = typeof(StringConverter).GetMethod(sOverideMethodName, new Type[] { typeof(ITypeDescriptorContext) });
MethodBuilder MethodImp = typeBuilder.DefineMethod(sOverideMethodName,
MethodDl.Attributes|MethodAttributes.Public,
MethodDl.CallingConvention, MethodDl.ReturnType,
new Type[] { typeof(ITypeDescriptorContext) });
if (null != gcOP)
{
gcOP(MethodImp);
}
typeBuilder.DefineMethodOverride(MethodImp, MethodDl);
}
private void GetStandardValuesSupportedImp(MethodBuilder MethodImp)
{
ILGenerator ilGen = MethodImp.GetILGenerator();
ilGen.Emit(OpCodes.Ldc_I4, 1);
ilGen.Emit(OpCodes.Ret);
}
private void GetStandardValuesImp(MethodBuilder MethodImp)
{
ILGenerator ilGen = MethodImp.GetILGenerator();
ConstructorInfo ci = typeof(StringConverter.StandardValuesCollection).GetConstructor(new Type[]{typeof(ArrayList)});
ilGen.Emit(OpCodes.Ldobj, m_valueArray.GetType());
ilGen.Emit(OpCodes.Newobj, ci);
ilGen.Emit(OpCodes.Stloc_0);
ilGen.Emit(OpCodes.Ret);
}
private void GetStandardValuesExclusiveImp(MethodBuilder MethodImp)
{
ILGenerator ilGen = MethodImp.GetILGenerator();
ilGen.Emit(OpCodes.Ldc_I4_1);
ilGen.Emit(OpCodes.Ret);
}
delegate void GenerateCodeOp(MethodBuilder MethodImp);
}
但是我发现那个被添加的属性没有多值显示。
而且经过我的测试,这个继承于StringConverter的类没有问题,我怀疑我的定制属性的那个部分语句写的有问题,我希望有相关的经验的人能够给予提示,在此表示感谢。