C# 在.NETC中的代码中创建类类型#

C# 在.NETC中的代码中创建类类型#,c#,.net,linq,class,expression,C#,.net,Linq,Class,Expression,当我研究System.Linq.Expression功能(在代码中创建表达式树、编译它们、执行它们)时,我问自己这是否也适用于类创建,特别是泛型类 我希望类似于Expression.Class()或Expression.GenericClass()的内容。看看这些方法,我没有看到任何一种。这将是非常实用的,因为我可以动态地构建业务对象。事实上这就是我需要的。如果在.net c中有其他方法可以实现这一点,我也会感兴趣。您应该研究,或者您可以研究.Net4的功能。两者都允许您在可以实例化的代码中创建

当我研究System.Linq.Expression功能(在代码中创建表达式树、编译它们、执行它们)时,我问自己这是否也适用于类创建,特别是泛型类


我希望类似于Expression.Class()或Expression.GenericClass()的内容。看看这些方法,我没有看到任何一种。这将是非常实用的,因为我可以动态地构建业务对象。事实上这就是我需要的。如果在.net c中有其他方法可以实现这一点,我也会感兴趣。

您应该研究,或者您可以研究.Net4的功能。两者都允许您在可以实例化的代码中创建新的对象类型。

有一个示例说明如何在一个框架codeplex项目中实现这一点

//定义程序集和模块。
AppDomain AppDomain=AppDomain.CurrentDomain;
AssemblyName AssemblyName=新的AssemblyName(“EmittedAssembly”);
AssemblyBuilder程序集=appDomain.DefinedDynamicAssembly(
assemblyName,AssemblyBuilderAccess.RunAndSave);
//程序集由可执行模块组成。对于单个模块
//程序集,模块名和文件名与
//程序集名称。
ModuleBuilder模块=assembly.DefinedDynamicModule(
assemblyName.Name,assemblyName.Name+“.dll”);
/////////////////////////////////////////////////////////////////////
//声明类型(类)。
// 
//将类声明为“ClassA”
TypeBuilder classA=module.DefineType(“classA”,TypeAttributes.Public);
//将类声明为“ClassB”
TypeBuilder classB=module.DefineType(“classB”,TypeAttributes.Public);
//定义字段stringField、classBField
FieldBuilder stringField=classA.DefineField(“stringField”,
typeof(字符串),FieldAttributes.Private);
FieldBuilder classBField=classA.DefineField(“classBField”,
classB,FieldAttributes.Public);
/////////////////////////////////////////////////////////////////////
//定义属性ClassBProperty
PropertyBuilder classBProperty=classA.DefineProperty(
“classB属性”,属性属性属性。无,classB,空);
//属性集的特殊属性集&get方法
MethodAttributes getSetAttr=MethodAttributes.Public|
MethodAttributes.SpecialName | MethodAttributes.HideBySig;
//定义ClassBProperty的“get”访问器方法
MethodBuilder classBGetProp=classA.DefineMethod(
“get_ClassBProperty”,getSetAttr,classB,Type.EmptyTypes);
ILGenerator classBGetIL=classBGetProp.GetILGenerator();
classBGetIL.Emit(操作码.Ldarg_0);
classBGetIL.Emit(操作码.Ldfld,classBField);
classBGetIL.Emit(操作码.Ret);
//定义ClassBProperty的“set”访问器方法
MethodBuilder classBSetProp=classA.DefineMethod(
“set_ClassBProperty”,getSetAttr,null,新类型[]{classB});
ILGenerator sampleSetIL=classBSetProp.GetILGenerator();
sampleSetIL.Emit(操作码.Ldarg_0);
sampleSetIL.Emit(操作码.Ldarg_1);
sampleSetIL.Emit(opcode.Stfld,classBField);
sampleSetIL.Emit(操作码.Ret);
//将get&set方法映射到PropertyBuilder
SetGetMethod(classBGetProp);
classBProperty.SetSetMethod(classBSetProp);
/////////////////////////////////////////////////////////////////////
//定义一个使用ClassB字段的方法
MethodBuilder ClassMethod=classA.DefineMethod(“ClassMethod”,
方法属性(公共);
//定义列表泛型和ienumerable泛型
类型listOf=类型(列表);
类型enumOf=typeof(IEnumerable);
类型listOfClassA=listOf.MakeGenericType(classA);
类型enumOfClassA=enumOf.MakeGenericType(classA);
//为ClassB定义方法ClassBMethod
MethodBuilder classBMethod=classB.DefineMethod(“classBMethod”,
Public、typeof(void)、新类型[]{listOfClassA});
ClassB方法定义参数(1,参数属性。无,“列表”);
//编写ClassMethod的主体,该主体称为ClassBMethod
ILGenerator ilgenA=classAMethod.GetILGenerator();
ilgenA.Emit(操作码Nop);
ilgenA.Emit(操作码.Ldarg_0);
ilgenA.Emit(操作码.Ldfld,类字段);
ilgenA.Emit(操作码.Ldnull);
ilgenA.Emit(操作码.Callvirt,classb方法);
ilgenA.Emit(操作码Ret);
/////////////////////////////////////////////////////////////////////
//创建类型。
// 
classA.CreateType();
CreateType();
/////////////////////////////////////////////////////////////////////
//保存程序集。
// 
Save(assemblyName.Name+“.dll”);

抱歉,这有点长..:-P

您是尝试动态创建类,还是尝试使用Linq扩展方法扩展现有类?创建类实际上是可能的,但我更愿意使用反射的Emit方法()而不是Linq,它主要是一种面向查询的技术,而不是元数据生成器。不过,您必须使用MSIL。我正在尝试动态创建一个类。MVC中的模型类-例如。稍后,在我创建它之后,我必须用Linq查询它。例如,作为MVC控制器类的一部分。
// Define the assembly and the module.

AppDomain appDomain = AppDomain.CurrentDomain;
AssemblyName assemblyName = new AssemblyName("EmittedAssembly");
AssemblyBuilder assembly = appDomain.DefineDynamicAssembly(
assemblyName, AssemblyBuilderAccess.RunAndSave);

// An assembly is made up of executable modules. For a single-module
// assembly, the module name and file name are the same as the 
// assembly name. 

ModuleBuilder module = assembly.DefineDynamicModule(
assemblyName.Name, assemblyName.Name + ".dll");


/////////////////////////////////////////////////////////////////////
// Declare the types (classes).
// 

// Declare the class "ClassA"
TypeBuilder classA = module.DefineType("ClassA", TypeAttributes.Public);
// Declare the class "ClassB"
TypeBuilder classB = module.DefineType("ClassB", TypeAttributes.Public);

// Define the fields stringField, classBField
FieldBuilder stringField = classA.DefineField("stringField",
typeof(string), FieldAttributes.Private);
FieldBuilder classBField = classA.DefineField("classBField",
classB, FieldAttributes.Public);

/////////////////////////////////////////////////////////////////////
// Define the property ClassBProperty
PropertyBuilder classBProperty = classA.DefineProperty(
    "ClassBProperty", PropertyAttributes.None, classB, null);

// The special set of attributes for the property set&get methods
MethodAttributes getSetAttr = MethodAttributes.Public |
    MethodAttributes.SpecialName | MethodAttributes.HideBySig;

// Define the "get" accessor method for ClassBProperty
MethodBuilder classBGetProp = classA.DefineMethod(
    "get_ClassBProperty", getSetAttr, classB, Type.EmptyTypes);
ILGenerator classBGetIL = classBGetProp.GetILGenerator();
classBGetIL.Emit(OpCodes.Ldarg_0);
classBGetIL.Emit(OpCodes.Ldfld, classBField);
classBGetIL.Emit(OpCodes.Ret);

// Define the "set" accessor method for ClassBProperty
MethodBuilder classBSetProp = classA.DefineMethod(
    "set_ClassBProperty", getSetAttr, null, new Type[] { classB });
ILGenerator sampleSetIL = classBSetProp.GetILGenerator();
sampleSetIL.Emit(OpCodes.Ldarg_0);
sampleSetIL.Emit(OpCodes.Ldarg_1);
sampleSetIL.Emit(OpCodes.Stfld, classBField);
sampleSetIL.Emit(OpCodes.Ret);

// Map the get&set methods to PropertyBuilder
classBProperty.SetGetMethod(classBGetProp);
classBProperty.SetSetMethod(classBSetProp);

/////////////////////////////////////////////////////////////////////
// Define a method that uses the classBField
MethodBuilder classAMethod = classA.DefineMethod("ClassAMethod", 
    MethodAttributes.Public);

// Define the list generics and ienumerable generic
Type listOf = typeof(List<>);
Type enumOf = typeof(IEnumerable<>);
Type listOfClassA = listOf.MakeGenericType(classA);
Type enumOfClassA = enumOf.MakeGenericType(classA);

// Define the method, ClassBMethod, for ClassB
MethodBuilder classBMethod = classB.DefineMethod("ClassBMethod", 
    MethodAttributes.Public, typeof(void), new Type[] { listOfClassA });
classBMethod.DefineParameter(1, ParameterAttributes.None, "list");

// Write the body of ClassAMethod that calls ClassBMethod
ILGenerator ilgenA = classAMethod.GetILGenerator();
ilgenA.Emit(OpCodes.Nop);
ilgenA.Emit(OpCodes.Ldarg_0);
ilgenA.Emit(OpCodes.Ldfld, classBField);
ilgenA.Emit(OpCodes.Ldnull);
ilgenA.Emit(OpCodes.Callvirt, classBMethod);
ilgenA.Emit(OpCodes.Ret);

/////////////////////////////////////////////////////////////////////
// Create the types.
// 

classA.CreateType();
classB.CreateType();    

/////////////////////////////////////////////////////////////////////
// Save the assembly.
// 

assembly.Save(assemblyName.Name + ".dll");