能从一个Type继承吗?
从一个类型继承出另一个类型大家都知道怎样写,比如:
class A
{
}
class B:A
{
}
这个代码中B继承了A,A是B的基类,可是,如果A是一个反射出来的类型,那么B怎样继承?
Type type=typeof(A);
class B:type???
{
}
[解决办法]
继承是设计时概念,反射是运行时概念。
怪异的需求产生怪异的设计。
[解决办法]
这也不行,type是动态得知的
[解决办法]
听听别人怎么说
[解决办法]
还是使用接口吧。
[解决办法]
[解决办法]
如一楼所说,继承是设计,反射式运行时。你可以试用类中类。
[解决办法]
一定要继承么?
可否用组合方式
Class B
{
直接把A类型的反射和调用等放这里面。
}
[解决办法]
msdn search emit
[解决办法]
要技术实现,只能使用Emit,如果说你觉得和问题关系不大,只能说明你不会用Emit,退一步就是根本没理解它的强大。我给你写一段用Emit创建运行时类型的例子,你可以参考下,那个Emit可是.NET的精华啊:
- C# code
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; }
[解决办法]
[解决办法]
要在运行时,搞个
class className:Typeof(。。。。)
个人认为不行。
但是我有个建议:
运行时得到type之后,让你的类型classname继承它。然后将classname的代码保存为一个文件。编译成dll,放进解决方案中。程序真正运行时再加载dll。
大概是这样:
stringbuilder classCode = string.format(" public class className : {0}",typof. { //类中的其他代码 }“)
saveClassCodeToFile(path)--- 编译成dll。。。。
[解决办法]
stringbuilder classCode = string.format(" public class className : {0}{ //类中的其他代码 }",typof something)
[解决办法]
楼主很扯,一个是运行时动态的获取东西,一个是设计时静态的语法。两个都不是一回事。
[解决办法]
我觉得lz应该把关注点放在DLR上面。
既然IronPython、IronRuby可以实现运行时解释脚本并且可以继承静态的类,那么一定有它的办法。
[解决办法]
[解决办法]
动态代理不就是了
[解决办法]
动态编译就可以的,只是调用这个类的方法属性都要通过反射的,
简单的示例
CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
CompilerParameters loParameters = new CompilerParameters();
loParameters.GenerateInMemory = true;
loParameters.ReferencedAssemblies.Add("System.dll");
loParameters.ReferencedAssemblies.Add("System.Data.dll");
loParameters.ReferencedAssemblies.Add("System.XML.dll");
CompilerResults result = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(loParameters, GenerateCodeBlocks());
if (result.Errors.HasErrors)
{
foreach (CompilerError error in result.Errors)
{
Console.WriteLine(error.ErrorText);
}
}
else
{
DataSet ds = new DataSet();
Assembly assembly = result.CompiledAssembly;
double calculated = Convert.ToDouble(assembly.GetType("demo.calculation").GetMethod("dowork").Invoke(null, new object[] { ds }));
Console.WriteLine(calculated);
}
//反射出来的一个类
static string GenerateCodeBlocks()
{
string code =
"using System;using System.Data;" +
"namespace demo" +
"{" +
"public static class calculation" +
"{" +
"public static double dowork(DataSet ds)" +
"{ return 1;}}}";
return code;
}
[解决办法]
LZ在想啥,继承是通过代码编程实现的。
难道你打算通过反射,让2个本没关系的类,发生关系吗?
[解决办法]
type是变量,也不是类型吧
[解决办法]
ILGenerator类的Emit方法的确可以干这个事情。
都知道.NET代码要经过两次编译才能最终执行。
ILGenerator类的Emit做的就是把 动态生成的代码 注入到IL中,接下来的事情就水到渠成了。
动态生成的代码就是像LZ这种需求:运行时才能得到基类(事先知道基类的话,那就直接继承了),然后根据基类得到子类。代码要执行需要编译,编译的结果就是IL代码,运行时生成的代码代码字符串,如何运行,那就必须转成IL能读懂的字符串。即IL代码,ILGenerator类的Emit做的就是替我们生成IL代码。