能从一个Type继承吗?
从一个类型继承出另一个类型大家都知道怎样写,比如:
class A
{
}
class B:A
{
}
这个代码中B继承了A,A是B的基类,可是,如果A是一个反射出来的类型,那么B怎样继承?
Type type=typeof(A);
class B:type???
{
}
[解决办法]
继承是设计时概念,反射是运行时概念。
怪异的需求产生怪异的设计。
[解决办法]
这也不行,type是动态得知的
[解决办法]
听听别人怎么说
[解决办法]
还是使用接口吧。
[解决办法]
public static TypeDes CreateType(IDictionary<string, Type> propertys, Type parent) { StringBuilder sb = new StringBuilder(); var e = propertys.GetEnumerator(); while (e.MoveNext()) { sb.Append(e.Current.Key + ":" + e.Current.Value.FullName + ","); } string pname = MD5Core.GetHashString(sb.ToString(0, sb.Length - 1)); TypeDes typedes; if (!typeCache.TryGetValue(pname, out typedes)) { AssemblyName aName = new AssemblyName(Guid.NewGuid().ToString()); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run); ModuleBuilder mb = ab.DefineDynamicModule(aName.Name); TypeBuilder tb = mb.DefineType(pname, TypeAttributes.Public, parent);//parent就是所需继承的父类 ConstructorBuilder ctor0 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); ILGenerator ctor0IL = ctor0.GetILGenerator(); ctor0IL.Emit(OpCodes.Ldarg_0); ctor0IL.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); ctor0IL.Emit(OpCodes.Ret); MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; FieldBuilder fb = null; PropertyBuilder pb = null; MethodBuilder mba = null; ILGenerator il = null; foreach (string key in propertys.Keys) { //创建私有字段,存放属性值 fb = tb.DefineField("_" + key, propertys[key], FieldAttributes.Private); //创建公有属性 pb = tb.DefineProperty(key, PropertyAttributes.HasDefault, propertys[key], null); //设置GET方法 mba = tb.DefineMethod("get_" + key, getSetAttr, propertys[key], Type.EmptyTypes); il = mba.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fb); il.Emit(OpCodes.Ret); pb.SetGetMethod(mba); //设置SET方法 mba = tb.DefineMethod("set_" + key, getSetAttr, null, new Type[] { propertys[key] }); il = mba.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Stfld, fb); il.Emit(OpCodes.Ret); pb.SetSetMethod(mba); } typedes = new TypeDes(tb.CreateType(), null); typeCache.Add(pname, typedes); } return typedes; }
[解决办法]
ILGenerator类的Emit做的就是把 动态生成的代码 注入到IL中,接下来的事情就水到渠成了。
动态生成的代码就是像LZ这种需求:运行时才能得到基类(事先知道基类的话,那就直接继承了),然后根据基类得到子类。代码要执行需要编译,编译的结果就是IL代码,运行时生成的代码代码字符串,如何运行,那就必须转成IL能读懂的字符串。即IL代码,ILGenerator类的Emit做的就是替我们生成IL代码。