2017-01-21 17 views
12

में एक प्रकार को कैसे निकालें सी # में, मैं .NET कोर के साथ रनटाइम पर एक नया प्रकार कैसे उत्सर्जित करूं? .NET 6 के लिए जो भी उदाहरण मिल सकते हैं, वे .NET कोर में काम नहीं कर रहे हैं (वे सभी वर्तमान ऐपडोमेन प्राप्त करने के साथ शुरू होते हैं, जो अब .NET कोर में मौजूद नहीं है)।.NET कोर

यदि संभव हो तो मैं एक उदाहरण की सराहना करता हूं जिसमें टाइप बनाने और प्रकार में एक संपत्ति जोड़ने शामिल है।

उत्तर

20

यहाँ अतः .NET में एक गतिशील प्रकार बनाने के बारे में पोस्ट किया जाता है 4.

How to dynamically create a class in C#?

और स्वीकार किए जाते हैं जवाब में AppDomain का सिर्फ एक प्रयोग है।

AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); 

यहाँ एक और एसओ नेट कोर में DefineDynamicAssembly समारोह के एक प्रतिस्थापन के बारे में पोस्ट है।

Is there any replace of AssemblyBuilder.DefineDynamicAssembly in .NET Core?

संदेश यह है:

AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()),AssemblyBuilderAccess.Run); 

"System.Reflection.Emit": "4.0.1" में nuget।

इसके अलावा, TypeBuilder में कोई अंतर है। CreateType फ़ंक्शन अब मौजूद नहीं हैं, इसके बजाय प्रकार बनाने के लिए हमें CreateTypeInfo का उपयोग करना चाहिए। और हाँ, यह फिर से एसओ पोस्ट से है।

CreateType missing from TypeBuilder. How to port this?

यहाँ एक प्रकार बनाने और प्रकार के गुण जोड़ने की संशोधित उदाहरण (.NET कोर के लिए) काम कर रहा है।

using System; 
using System.Collections.Generic; 
using System.Reflection.Emit; 
using System.Reflection; 

namespace ConsoleApp1 
{ 
    public class FieldDescriptor 
    { 
     public FieldDescriptor(string fieldName, Type fieldType) 
     { 
      FieldName = fieldName; 
      FieldType = fieldType; 
     } 
     public string FieldName { get; } 
     public Type FieldType { get; } 
    } 

    public static class MyTypeBuilder 
    { 
     public static object CreateNewObject() 
     { 
      var myTypeInfo = CompileResultTypeInfo(); 
      var myType = myTypeInfo.AsType(); 
      var myObject = Activator.CreateInstance(myType); 

      return myObject; 
     } 

     public static TypeInfo CompileResultTypeInfo() 
     { 
      TypeBuilder tb = GetTypeBuilder(); 
      ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); 

      var yourListOfFields = new List<FieldDescriptor>() 
      { 
       new FieldDescriptor("YourProp1",typeof(string)), 
       new FieldDescriptor("YourProp2", typeof(int)) 
      }; 
      foreach (var field in yourListOfFields) 
       CreateProperty(tb, field.FieldName, field.FieldType); 

      TypeInfo objectTypeInfo = tb.CreateTypeInfo(); 
      return objectTypeInfo; 
     } 

     private static TypeBuilder GetTypeBuilder() 
     { 
      var typeSignature = "MyDynamicType"; 
      var an = new AssemblyName(typeSignature); 
      var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run); 
      ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); 
      TypeBuilder tb = moduleBuilder.DefineType(typeSignature, 
        TypeAttributes.Public | 
        TypeAttributes.Class | 
        TypeAttributes.AutoClass | 
        TypeAttributes.AnsiClass | 
        TypeAttributes.BeforeFieldInit | 
        TypeAttributes.AutoLayout, 
        null); 
      return tb; 
     } 

     private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) 
     { 
      FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private); 

      PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null); 
      MethodBuilder getPropMthdBldr = tb.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 = 
       tb.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); 
     } 
    } 
}