我有一个在运行时建立的类(RClass),也有一个通用类B,我如何创建一种类型的DataLoader并使用其方法。

public interface IDataLoader<GType>
{
//some code
   GType SampleMethod();
}

public class DataLoader <GType>: IDataLoader<GType>
{
  GType SampleMethod(){
    //some code
  }
}

//class "RClass" created in runtime
MyClassBuilder MCB=new MyClassBuilder("RClass");
var myclass = MCB.CreateObject(new string[3] { "id", "name", "link" }, new Type[3] { typeof(int), typeof(string), typeof(string) });
Type myclassType = myclass.GetType();

var dta = typeof(DataLoader<>).MakeGenericType(myclassType);
// ?????
var gs = (???)Activator.CreateInstance(dta);
gs.SampleMethod();

对于在运行时构建类,我使用本文http://www.codeproject.com/Articles/13337/Introduction-to-Creating-Dynamic-Types-with-Reflec

MyClassBuilder的完整详细信息是

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
using Faroid;

namespace Faroid
{
    namespace Runtime
    {
    public class ORMapperFactory  
    {  
        string asmName;
        AssemblyName assemblyName;
        AssemblyBuilder asmBuilder;
        ModuleBuilder modBuilder;

        public ORMapperFactory(string ClassName)  
        {  
            asmName = ClassName;  
        }

        void GenerateAssemblyAndModule()
        {
            if (asmBuilder == null)
            {
                assemblyName = new AssemblyName();
                assemblyName.Name = asmName;
                AppDomain thisDomain = Thread.GetDomain();
                asmBuilder = thisDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);

                modBuilder = asmBuilder.DefineDynamicModule(asmBuilder.GetName().Name, false);
            }
        }

        TypeBuilder CreateType(ModuleBuilder moduleBuilder, string typeName)
        {
            TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, 
                TypeAttributes.Public | 
                TypeAttributes.Class |
                TypeAttributes.AutoClass | 
                TypeAttributes.AnsiClass | 
                TypeAttributes.BeforeFieldInit | 
                TypeAttributes.AutoLayout, 
                typeof(object), 
                new Type[] {typeof(IORMapper)});

            return typeBuilder;
        }

        public IORMapper CreateObject(string[] PropertyNames,Type[]Types, bool returnAdapter)  
        {  
            if(PropertyNames.Length!=Types.Length)  
            {  
                Console.WriteLine("The number of property names should match their corresopnding types number");  
            }  

            TypeBuilder DynamicClass = CreateClass ();  
            CreateConstructor (DynamicClass);
            for (int ind = 0; ind < PropertyNames.Count (); ind++) {
                CreateProperty (DynamicClass, PropertyNames [ind], Types [ind]);
                //cache adapter instance
            //  adapters.Add(dt.TableName, dra);
            }

            Type type = DynamicClass.CreateType();  

            //Create an instance of the DataRowAdapter
            var dra = (IORMapper)Activator.CreateInstance(type, true);

            //cache adapter instance
            //adapters.Add(dt.TableName, dra);

            //if just initializing adapter, dont return instance
            return !returnAdapter ? null : dra;

        }

        TypeBuilder CreateClass()  
        { 
            GenerateAssemblyAndModule ();
            TypeBuilder typeBuilder = CreateType (modBuilder, assemblyName.FullName);
            return typeBuilder;  
        }

        void CreateConstructor(TypeBuilder typeBuilder)
        {
            ConstructorBuilder constructor = typeBuilder.DefineConstructor(
                MethodAttributes.Public | 
                MethodAttributes.SpecialName | 
                MethodAttributes.RTSpecialName, 
                CallingConventions.Standard, 
                new Type[0]);
            //Define the reflection ConstructorInfor for System.Object
            ConstructorInfo conObj = typeof(object).GetConstructor(new Type[0]);

            //call constructor of base object
            ILGenerator il = constructor.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, conObj);
            il.Emit(OpCodes.Ret);
        }

//      static void CreateConstructor(TypeBuilder typeBuilder)  
//      {  
//          typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);  
//      }

        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);  
        }
    }
}
}

===============>>#1 票数:1 已采纳

简而言之,你不能:-)

有多种可能的解决方案:

  • 非通用接口:

     public interface IDataLoader { //some code object SampleMethod(); } 

    例如,这是通过IEnumerable / IEnumerable<T>完成的

  • dynamic

     dynamic gs = Activator.CreateInstance(dta); 
  • 您将对象传递给一个类,该类将使用反射来“探索”它(例如,通常是DataGrid

  • 您将所有您想做的事情包含在通用方法中:

     public void Work<GType>(IDataLoader<GType> dataLoader) { // Here you can work with the IDataLoader<GType> } 

    然后通过反射调用Work<GType>()

  ask by eager translate from so

未解决问题?本站智能推荐:

3回复

为什么我可以在运行时从泛型类型继承而不能在编译时继承?

所以我在做一些实验,结果发现: 另一方面,这失败了: 工作正常。 如果我仍然可以在运行时做到这一点,似乎仅在编译时就可以使用将节省很多麻烦。
1回复

在运行时创建数组类型

我想在运行时获得一个类型的“数组类型”。 我不需要数组的实例,只需要Type。 我目前使用以下方法。 没有创建数组实例有没有更好的解决方案? 注意:我不能使用Type.GetType(elementType.FullName + "[]")因为我在运行时通过Reflection
1回复

如何在运行时仅在类上添加属性?

我设法在运行时使用反射发射创建了此类: 像这样: 我真正想要的是这样声明我的班级: 并且在运行时仅添加这些属性。 对于名字字段,我正在考虑这样的事情 如何使建造者进入那个领域?
1回复

如何在运行时创建类的实例

我在运行时使用Reflection.Emit编写了一些创建类和属性的方法,我的代码是: 并使用这样的代码 现在我想创建Test类的实例并为属性值设置值,但我不知道怎么做,请帮助我,谢谢所有。
2回复

我可以在运行时设置字段的类型,一个类中在C#中新创建的类型?

我正在使用Reflection.Emit和TypeBuilder在运行时创建新类型。 我的设置是这样的: 问题是MyClass.MyField是用类型object声明的,因此,当将可转换类型分配给MyClass.MyField时,不会调用存在于该新类型的隐式转换运算符。 有没有一种方
1回复

使用反射在运行时创建的类型的属性上添加属性

我试图在运行时创建一个类型,在我为此类型添加的每个属性上添加一个StuckAttribute属性。 类型生成器: 物业开发商: 我创建了一个简单的测试,以检查StuckAttribute是否在属性上。 如您所见,我试图在每个PropertyInfo元素上获取属性调用Get
2回复

DynamicMethod具有泛型类型参数

是否可以使用泛型类型参数定义DynamicMethod? MethodBuilder类具有DefineGenericParameters方法。 DynamicMethod有对应的吗? 例如,是否可以使用DynamicMethod创建具有签名的方法?
4回复

如何在运行时向方法添加属性?

我们使用Microsoft.Practices.CompositeUI.EventBroker来处理我们的应用程序中的事件订阅和发布。 可行的方法是向事件添加属性,指定主题名称,如下所示: 然后你用你的处理程序添加另一个属性,使用相同的主题名称,如下所示: 然后将对象传递给Ev
2回复

是否可以在c#中使用在运行时创建的类型的隐式转换?

我在运行时使用Reflection.Emit创建一个类型。 问题是每当我实例化一个新类型的实例时,我必须使用object或dynamic因为在编译时不知道该类型。 除了在分配期间我希望另一种类型隐式地转换为新类型时,这工作正常。 该变量愉快地采用新值并且它是相应的类型而不尝试强制转换为其当
1回复

动态创建具有自引用约束的c#泛型类型

我有一个看起来像这样的泛型类型 我需要动态构造类型T.所以它看起来像这样: 可以这样做吗?