首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

能从一个Type承袭吗

2012-09-24 
能从一个Type继承吗?从一个类型继承出另一个类型大家都知道怎样写,比如:class A{}class B:A{}这个代码中B

能从一个Type继承吗?
从一个类型继承出另一个类型大家都知道怎样写,比如:

class A
{
}

class B:A
{
}

这个代码中B继承了A,A是B的基类,可是,如果A是一个反射出来的类型,那么B怎样继承?

Type type=typeof(A);

class B:type???
{
}

[解决办法]
继承是设计时概念,反射是运行时概念。

怪异的需求产生怪异的设计。
[解决办法]
这也不行,type是动态得知的
[解决办法]
听听别人怎么说
[解决办法]
还是使用接口吧。
[解决办法]

探讨

我有一个.net的DLL,里面定义了一个抽像的基类,这个类需要被继承后才能调用。
然后这个DLL不能正常的被引用,只能通过Assembly.Load方法来加载,那么这个DLL中的类型怎样被继承又怎样重写基类的方法呢?

如果能直接引用就可以编写它的代码了,可是现在是Load的后期加载。怎么继承这个类型?

其实这不是怪异的想法。
如果是一个DLL被加密,加密后只能通过Load来加载,……

[解决办法]
如一楼所说,继承是设计,反射式运行时。你可以试用类中类。
[解决办法]
一定要继承么?
可否用组合方式
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可以实现运行时解释脚本并且可以继承静态的类,那么一定有它的办法。
[解决办法]
探讨
我有一个.net的DLL,里面定义了一个抽像的基类,这个类需要被继承后才能调用。
然后这个DLL不能正常的被引用,只能通过Assembly.Load方法来加载,那么这个DLL中的类型怎样被继承又怎样重写基类的方法呢?

如果能直接引用就可以编写它的代码了,可是现在是Load的后期加载。怎么继承这个类型?

其实这不是怪异的想法。
如果是一个DLL被加密,加密后只能通过Load来加载,……

[解决办法]
动态代理不就是了
[解决办法]
动态编译就可以的,只是调用这个类的方法属性都要通过反射的,

简单的示例

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代码。

热点排行