首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >有没有办法在运行时构建一个新的类型?

有没有办法在运行时构建一个新的类型?
EN

Stack Overflow用户
提问于 2009-05-30 08:35:27
回答 3查看 13K关注 0票数 24

我要问一个可能听起来很奇怪的问题。

有没有办法在运行时创建一个新的类?或者至少向现有类添加一个新属性。

我的意思是创建一个不存在的类,而不是现有类的实例。稍后我可以使用反射来加载和使用这个类。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-05-30 09:02:28

无法向现有类型添加属性,但可以在运行时使用Reflection.Emit创建新类型。这是相当复杂的东西,大概是这样的:

代码语言:javascript
复制
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(
      assemblyName , AssemblyBuilderAccess.Run, assemblyAttributes);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("ModuleName");
TypeBuilder typeBuilder = moduleBuilder.DefineType(
      "MyNamespace.TypeName" , TypeAttributes.Public);

typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

// Add a method
newMethod = typeBuilder.DefineMethod("MethodName" , MethodAttributes.Public);

ILGenerator ilGen = newMethod.GetILGenerator();

// Create IL code for the method
ilGen.Emit(...);

// ...

// Create the type itself
Type newType = typeBuilder.CreateType();

这段代码只是一个示例。它可能包含错误。

您还可以通过在运行时使用System.CodeDom编译C#源代码来生成类,但我对此了解不多。

票数 29
EN

Stack Overflow用户

发布于 2009-05-30 08:43:24

看一下System.Reflection.Emit名称空间。我自己从来没有用过它,但是这个名称空间中的类可以用来生成IL (中间语言)。

票数 5
EN

Stack Overflow用户

发布于 2009-05-30 09:04:13

这并不是一个奇怪的问题--在某些情况下,它可能非常有用。例如,我有时会使用此技术进行性能测试:

代码语言:javascript
复制
public static Type[] DynamicTypes;

public void CreateObjects()
{
  var codeNamespace = new CodeNamespace( "DynamicClasses" );
  codeNamespace.Imports.Add( new CodeNamespaceImport( "System" ) );
  codeNamespace.Imports.Add( new CodeNamespaceImport( "System.ComponentModel" ) );

  for( var i = 0; i < 2000; i++ )
  {
    var classToCreate = new CodeTypeDeclaration( "DynamicClass_" + i )
    {
      TypeAttributes = TypeAttributes.Public
    };
    var codeConstructor1 = new CodeConstructor
    {
      Attributes = MemberAttributes.Public
    };
    classToCreate.Members.Add( codeConstructor1 );

    codeNamespace.Types.Add( classToCreate );
  }

  var codeCompileUnit = new CodeCompileUnit();
  codeCompileUnit.Namespaces.Add( codeNamespace );

  var compilerParameters = new CompilerParameters
  {
    GenerateInMemory = true,
    IncludeDebugInformation = true,
    TreatWarningsAsErrors = true,
    WarningLevel = 4
  };
  compilerParameters.ReferencedAssemblies.Add( "System.dll" );

  var compilerResults = new CSharpCodeProvider().CompileAssemblyFromDom( compilerParameters, codeCompileUnit );

  if( compilerResults == null )
  {
    throw new InvalidOperationException( "ClassCompiler did not return results." );
  }
  if( compilerResults.Errors.HasErrors )
  {
    var errors = string.Empty;
    foreach( CompilerError compilerError in compilerResults.Errors )
    {
      errors += compilerError.ErrorText + "\n";
    }
    Debug.Fail( errors );
    throw new InvalidOperationException( "Errors while compiling the dynamic classes:\n" + errors );
  }

  var dynamicAssembly = compilerResults.CompiledAssembly;
  DynamicTypes = dynamicAssembly.GetExportedTypes();
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/929349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档