কীভাবে গতিশীলভাবে একটি ক্লাস তৈরি করা যায়?


221

আমার একটি ক্লাস রয়েছে যা দেখতে এটির মতো দেখাচ্ছে:

public class Field
{
    public string FieldName;
    public string FieldType;
}

এবং List<Field>মান সহ একটি বস্তু :

{"EmployeeID","int"},
{"EmployeeName","String"},
{"Designation","String"}

আমি এমন একটি শ্রেণি তৈরি করতে চাই যা এরকম দেখাচ্ছে:

Class DynamicClass
{
    int EmployeeID,
    String EmployeeName,
    String Designation
}

এই কাজ করতে কোন উপায় আছে কি?

আমি এটি রানটাইমে উত্পন্ন করতে চাই। আমি আমার ফাইল সিস্টেমে থাকা কোনও শারীরিক সিএস ফাইল চাই না।


4
আপনি কি ক্লাসটি রানটাইমে ব্যবহার করতে চান বা কেবল ফাইল তৈরি করতে চান?
দামিয়ান লেজস্কিওস্কি - ভ্যাশ

আমি এটি রানটাইমে উত্পন্ন করতে চাই। আমি আমার ফাইল সিস্টেমে থাকা কোনও শারীরিক সিএস ফাইল চাই না। এর আগে উল্লেখ না করার জন্য দুঃখিত।
অশ্বনাচার্য

16
তুমি আমাদের কি মনস্থ না একটি মোটামুটি একটা ধারণা দিতে পারি না এই শ্রেণীর সাথে?
জাস্টিন

3
উদাহরণস্বরূপ, জাস্টিন রানটাইম-সমাধানযুক্ত ইন্টারফেস প্রয়োগ করে।
এজেন্টফায়ার

কেউ এটিকে খাওয়াতে পারেSystem.ServiceModel.ChannelFactory<MyDynamicInterface>
ইলিয়া সেমেনভ

উত্তর:


297

হ্যাঁ, আপনি এর জন্য System.Reflection.Emitনেমস্পেস ব্যবহার করতে পারেন । এটির সাথে যদি আপনার কোনও অভিজ্ঞতা না থাকে তবে তা সরাসরি নয় but তবে এটি অবশ্যই সম্ভব।

সম্পাদনা করুন: এই কোডটি ত্রুটিযুক্ত হতে পারে তবে এটি আপনাকে সাধারণ ধারণা দেবে এবং আশা করা যায় যে লক্ষ্যটির দিকে একটি ভাল শুরু হবে।

using System;
using System.Reflection;
using System.Reflection.Emit;

namespace TypeBuilderNamespace
{
    public static class MyTypeBuilder
    {
        public static void CreateNewObject()
        {
            var myType = CompileResultType();
            var myObject = Activator.CreateInstance(myType);
        }
        public static Type CompileResultType()
        {
            TypeBuilder tb = GetTypeBuilder();
            ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);

            // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type)
            foreach (var field in yourListOfFields)
                CreateProperty(tb, field.FieldName, field.FieldType);

            Type objectType = tb.CreateType();
            return objectType;
        }

        private static TypeBuilder GetTypeBuilder()
        {
            var typeSignature = "MyDynamicType";
            var an = new AssemblyName(typeSignature);
            AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, 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);
        }
    }
}

2
অসাধারণ!! আপনি কি আমাকেও বলতে পারেন যে কীভাবে কমপাইলারেসাল্টটাইপ () পদ্ধতি দ্বারা ফেরত পাঠানো একটি অবজেক্ট তৈরি করা যায়?
অশ্বনাচার্য

4
আপনি এটির জন্য System.Activator ব্যবহার করতে পারেন। উত্তরটি একটি উদাহরণ সহ আপডেট করব।
দানিজেলস

4
আপনার ডায়নামিক ধরণের ক্ষেত্রগুলি পরীক্ষা করতে, পড়তে এবং আপডেট করতে আপনাকে প্রতিবিম্বটি ব্যবহার করতে হবে তাও নোট করুন। আপনি যদি ইন্টেলিজেন্স চান এবং কোনও প্রতিবিম্ব চান না, আপনার স্ট্যাটিক বেস ক্লাস বা ইন্টারফেস থাকতে হবে যা আপনার গতিশীল শ্রেণীর উত্তরাধিকার সূত্রে প্রাপ্ত এবং এতে কাস্ট করা যেতে পারে। সেক্ষেত্রে আপনি গেটটাইপবিল্ডার () পদ্ধতিটি পরিবর্তন করতে পারেন এবং মডিউলবিল্ডারকে পরিবর্তন করতে পারেন the স্ট্যাটিক টাইপটিকে শেষ প্যারামিটার হিসাবে অন্তর্ভুক্ত করতে (এখন নাল এখন)
ড্যানিজেল

2
কেউ কীভাবে বিষয়টি তৈরির পরে কীভাবে ব্যবহার করবেন তা ব্যাখ্যা করতে পারেন
HELP_ME

3
ক্লাবটি তৈরি করার জন্য @ বুগজ উপরের কোডটি ব্যবহার করুন, তারপরে বেস শ্রেণিতে আপনি এই পদ্ধতিটি যুক্ত করতে পারেন: পাবলিক শূন্য সেটওয়ালু <T> (স্ট্রিংয়ের নাম, টি মান) {গেটটাইপ () গেটপ্রোপার্টি (নাম) etসেটভ্যালু (এটি, মান) ); }
stricq

71

এটি কিছু কাজ গ্রহণ করবে, তবে অবশ্যই অসম্ভব নয়।

আমি যা করেছি তা হ'ল:

  • একটি স্ট্রিংয়ে সি # উত্স তৈরি করুন (কোনও ফাইলে লেখার দরকার নেই),
  • এটি Microsoft.CSharp.CSharpCodeProvider(কমপ্লেসঅ্যাস্পেস্প্রোমসোর্স) মাধ্যমে চালান
  • উত্পন্ন প্রকারটি সন্ধান করুন
  • এবং এই ধরণের একটি উদাহরণ তৈরি করুন ( Activator.CreateInstance)

এমএসআইএল নিঃসরণ করার পরিবর্তে আপনি ইতিমধ্যে জেনে থাকা সি # কোডটি মোকাবেলা করতে পারবেন।

তবে এটি সর্বোত্তমভাবে কাজ করে যদি আপনার শ্রেণি কিছু ইন্টারফেস প্রয়োগ করে (বা কিছু বেসক্লাস থেকে প্রাপ্ত), অন্যথায় কলিং কোডটি (পড়ুন: সংকলক) কীভাবে রানটাইমের সময় উত্পন্ন হবে সেই শ্রেণি সম্পর্কে জানতে?


7
এই আলোচনাটি দেখতে চান হতে পারে: প্রতিচ্ছবি-এমিট-বনাম-কোডেডম
নওফাল

1
@ নওফাল, অশ্বনাচার্য, রানটাইমে ক্লাসের সদস্যদের সাথে প্রাথমিকভাবে একটি তালিকায় অন্তর্ভুক্ত থাকা ক্লাসটি গতিশীলভাবে তৈরি করতে চেয়েছিলেন। আমি মনে করি না এটি রানটাইমের সময় উত্পন্ন কোনও ফাইলের মধ্যে রাখা ভাল পারফরম্যান্স সমাধান হতে পারে।
sodjsn26fr

38

এছাড়াও আপনি পরিবর্তনশীল ব্যবহার করে একটি বর্গ তৈরি করতে পারেন DynamicObject

public class DynamicClass : DynamicObject
{
    private Dictionary<string, KeyValuePair<Type, object>> _fields;

    public DynamicClass(List<Field> fields)
    {
        _fields = new Dictionary<string, KeyValuePair<Type, object>>();
        fields.ForEach(x => _fields.Add(x.FieldName,
            new KeyValuePair<Type, object>(x.FieldType, null)));
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (_fields.ContainsKey(binder.Name))
        {
            var type = _fields[binder.Name].Key;
            if (value.GetType() == type)
            {
                _fields[binder.Name] = new KeyValuePair<Type, object>(type, value);
                return true;
            }
            else throw new Exception("Value " + value + " is not of type " + type.Name);
        }
        return false;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        result = _fields[binder.Name].Value;
        return true;
    }
}

আমি সমস্ত শ্রেণীর ক্ষেত্রগুলি _fieldsতাদের অভিধান এবং প্রকারের সাথে একটি অভিধানে সঞ্চয় করি । উভয় পদ্ধতি হ'ল কিছু বৈশিষ্ট্যের মান পেতে বা সেট করতে set dynamicএই শ্রেণীর উদাহরণ তৈরি করতে আপনাকে অবশ্যই কীওয়ার্ডটি ব্যবহার করতে হবে ।

আপনার উদাহরণ সহ ব্যবহার:

var fields = new List<Field>() { 
    new Field("EmployeeID", typeof(int)),
    new Field("EmployeeName", typeof(string)),
    new Field("Designation", typeof(string)) 
};

dynamic obj = new DynamicClass(fields);

//set
obj.EmployeeID = 123456;
obj.EmployeeName = "John";
obj.Designation = "Tech Lead";

obj.Age = 25;             //Exception: DynamicClass does not contain a definition for 'Age'
obj.EmployeeName = 666;   //Exception: Value 666 is not of type String

//get
Console.WriteLine(obj.EmployeeID);     //123456
Console.WriteLine(obj.EmployeeName);   //John
Console.WriteLine(obj.Designation);    //Tech Lead

সম্পাদনা: এবং এখানে আমার ক্লাসটি কেমন দেখাচ্ছে Field:

public class Field
{
    public Field(string name, Type type)
    {
        this.FieldName = name;
        this.FieldType = type;
    }

    public string FieldName;

    public Type FieldType;
}

1
কনস্ট্রাক্টরের সাথে ক্ষেত্রগুলি আরম্ভ করার প্রয়োজন না হওয়া পর্যন্ত আমি এই পদ্ধতির পছন্দ করেছি। অর্থাত্ dynamic obj = new DynamicClass(fields){EmployeeId=123456;EmployeeName = "John"; Designation = "Tech Lead";}এটি করা সত্যিই দুর্দান্ত হবে।
rey_coder

14

আমি জানি আমি এই পুরানো কাজটি আবার খুলি তবে সি # 4.0 দিয়ে এই কাজটি একেবারেই বেদাহীন।

dynamic expando = new ExpandoObject();
expando.EmployeeID=42;
expando.Designation="unknown";
expando.EmployeeName="curt"

//or more dynamic
AddProperty(expando, "Language", "English");

আরও তথ্যের জন্য https://www.oreilly.com/learning/building-c-objects-dynamically দেখুন


হ্যাঁ, তবে আপনি এখানে সুরক্ষা হারাবেন। ধরণের সুরক্ষা সংরক্ষণের সময় আমরা কি অনুরূপ কিছু করতে পারি?
শক্ত প্রশ্নগুলি

13

আমি এ জাতীয় গতিশীল ক্লাসগুলির উদ্দেশ্যে ব্যবহার জানি না এবং কোড জেনারেশন এবং রান টাইম সংকলন করা যেতে পারে তবে কিছুটা প্রচেষ্টা নেওয়া দরকার। হতে পারে অনামিক প্রকারগুলি আপনাকে সহায়তা করবে, এরকম কিছু:

var v = new { EmployeeID = 108, EmployeeName = "John Doe" };

7
আপনি ক্ষেত্রের নামগুলি হার্ড কোড করতে পারবেন না। তিনি তাদের প্রদান করছেন Field.FieldName। ক্ষেত্রের নামগুলি হার্ড কোড করা উদ্দেশ্যকে পরাভূত করে। যদি আপনাকে এটি করতে হয়, আপনি পাশাপাশি বর্গ তৈরি করতে পারেন।
toddmo

9

আপনি কোডডোমটি দেখতে চান । এটি কোডের উপাদানগুলি সংজ্ঞায়িত করতে এবং সংকলনের অনুমতি দেয়। এমএসডিএন উদ্ধৃত:

... একটি সমর্থিত প্রোগ্রামিং ভাষার জন্য কোডডম কোড জেনারেটর ব্যবহার করে এই অবজেক্ট গ্রাফটি উত্স কোড হিসাবে রেন্ডার করা যেতে পারে। কোডডোম বাইনারি সমাবেশে উত্স কোডটি সংকলন করতেও ব্যবহার করা যেতে পারে।


আমি এটি রানটাইমে উত্পন্ন করতে চাই। আমি আমার ফাইল সিস্টেমে থাকা কোনও শারীরিক সিএস ফাইল চাই না। এর আগে উল্লেখ না করার জন্য দুঃখিত।
অশ্বনাচার্য

1
@ অশ্বনাচার্য: আপনি উত্স ফাইল উত্পন্ন করতে এবং রানটাইম সময়ে এটি সংকলন করার জন্য কোডডম ব্যবহার করতে পারেন!
হেমন্ত

1
যদিও সাবধান থাকুন যে কোডডোম সংকলকটি একটি কাঁচা স্ট্রিং নেয় এবং তাই আপনি এক্সএসএস এবং এসকিউএল ইঞ্জেকশনে ব্যবহৃত "কোড সন্নিবেশ আক্রমণগুলি" বিবেচনা করতে পারেন।
9:34 এ cwap

6

@ ড্যানিজেলের উত্তরের ভিত্তিতে, গতিশীলভাবে ভিবি.এনইটিতে একটি শ্রেণী তৈরি করুন:

Imports System.Reflection
Imports System.Reflection.Emit

Public Class ObjectBuilder

Public Property myType As Object
Public Property myObject As Object

Public Sub New(fields As List(Of Field))
    myType = CompileResultType(fields)
    myObject = Activator.CreateInstance(myType)
End Sub

Public Shared Function CompileResultType(fields As List(Of Field)) As Type
    Dim tb As TypeBuilder = GetTypeBuilder()
    Dim constructor As ConstructorBuilder = tb.DefineDefaultConstructor(MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.RTSpecialName)

    For Each field In fields
        CreateProperty(tb, field.Name, field.Type)
    Next

    Dim objectType As Type = tb.CreateType()
    Return objectType
End Function

Private Shared Function GetTypeBuilder() As TypeBuilder
    Dim typeSignature = "MyDynamicType"
    Dim an = New AssemblyName(typeSignature)
    Dim assemblyBuilder As AssemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run)
    Dim moduleBuilder As ModuleBuilder = assemblyBuilder.DefineDynamicModule("MainModule")
    Dim tb As TypeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.[Public] Or TypeAttributes.[Class] Or TypeAttributes.AutoClass Or TypeAttributes.AnsiClass Or TypeAttributes.BeforeFieldInit Or TypeAttributes.AutoLayout, Nothing)
    Return tb
End Function

Private Shared Sub CreateProperty(tb As TypeBuilder, propertyName As String, propertyType As Type)
    Dim fieldBuilder As FieldBuilder = tb.DefineField("_" & propertyName, propertyType, FieldAttributes.[Private])

    Dim propertyBuilder As PropertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, Nothing)
    Dim getPropMthdBldr As MethodBuilder = tb.DefineMethod("get_" & propertyName, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, propertyType, Type.EmptyTypes)
    Dim getIl As ILGenerator = getPropMthdBldr.GetILGenerator()

    getIl.Emit(OpCodes.Ldarg_0)
    getIl.Emit(OpCodes.Ldfld, fieldBuilder)
    getIl.Emit(OpCodes.Ret)

    Dim setPropMthdBldr As MethodBuilder = tb.DefineMethod("set_" & propertyName, MethodAttributes.[Public] Or MethodAttributes.SpecialName Or MethodAttributes.HideBySig, Nothing, {propertyType})

    Dim setIl As ILGenerator = setPropMthdBldr.GetILGenerator()
    Dim modifyProperty As Label = setIl.DefineLabel()
    Dim exitSet As Label = 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)
End Sub

End Class

5

এছাড়াও আপনি পরিবর্তনশীল ব্যবহার করে একটি বর্গ তৈরি করতে পারেন DynamicExpressions

যেহেতু 'অভিধানগুলিতে কমপ্যাক্ট আরম্ভকারী রয়েছে এবং কী সংঘর্ষগুলি পরিচালনা করে, আপনি এরকম কিছু করতে চাইবেন।

  var list = new Dictionary<string, string> {
    {
      "EmployeeID",
      "int"
    }, {
      "EmployeeName",
      "String"
    }, {
      "Birthday",
      "DateTime"
    }
  };

অথবা আপনার সিরিয়ালাইজড স্ট্রিং অবজেক্টটিকে ম্যানেজযোগ্য কিছুতে তৈরি করতে আপনি একটি JSON রূপান্তরকারী ব্যবহার করতে চাইতে পারেন।

তারপরে System.Linq.Dynamic ব্যবহার করে;

  IEnumerable<DynamicProperty> props = list.Select(property => new DynamicProperty(property.Key, Type.GetType(property.Value))).ToList();

  Type t = DynamicExpression.CreateClass(props);

বাকীটি কেবলমাত্র সিস্টেম.প্রকাশন ব্যবহার করছে।

  object obj = Activator.CreateInstance(t);
  t.GetProperty("EmployeeID").SetValue(obj, 34, null);
  t.GetProperty("EmployeeName").SetValue(obj, "Albert", null);
  t.GetProperty("Birthday").SetValue(obj, new DateTime(1976, 3, 14), null);
}  

4

যারা গতিশীল শ্রেণি তৈরি করতে চান কেবলমাত্র বৈশিষ্ট্য (যেমন পোকো), এবং এই শ্রেণীর একটি তালিকা তৈরি করুন। পরে প্রদত্ত কোডটি ব্যবহার করে, এটি একটি গতিশীল শ্রেণি তৈরি করবে এবং এর একটি তালিকা তৈরি করবে।

var properties = new List<DynamicTypeProperty>()
{
    new DynamicTypeProperty("doubleProperty", typeof(double)),
    new DynamicTypeProperty("stringProperty", typeof(string))
};

// create the new type
var dynamicType = DynamicType.CreateDynamicType(properties);
// create a list of the new type
var dynamicList = DynamicType.CreateDynamicList(dynamicType);

// get an action that will add to the list
var addAction = DynamicType.GetAddAction(dynamicList);

// call the action, with an object[] containing parameters in exact order added
addAction.Invoke(new object[] {1.1, "item1"});
addAction.Invoke(new object[] {2.1, "item2"});
addAction.Invoke(new object[] {3.1, "item3"});

পূর্ববর্তী কোডগুলি যে ক্লাসগুলি ব্যবহার করে সেগুলি এখানে।

দ্রষ্টব্য: আপনাকে মাইক্রোসফ্ট.কোডএ্যানালাইসিস.সিএসআরপ লাইব্রেরিটি উল্লেখ করতে হবে।

       /// <summary>
    /// A property name, and type used to generate a property in the dynamic class.
    /// </summary>
    public class DynamicTypeProperty
    {
        public DynamicTypeProperty(string name, Type type)
        {
            Name = name;
            Type = type;
        }
        public string Name { get; set; }
        public Type Type { get; set; }
    }

   public static class DynamicType
    {
        /// <summary>
        /// Creates a list of the specified type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static IEnumerable<object> CreateDynamicList(Type type)
        {
            var listType = typeof(List<>);
            var dynamicListType = listType.MakeGenericType(type);
            return (IEnumerable<object>) Activator.CreateInstance(dynamicListType);
        }

        /// <summary>
        /// creates an action which can be used to add items to the list
        /// </summary>
        /// <param name="listType"></param>
        /// <returns></returns>
        public static Action<object[]> GetAddAction(IEnumerable<object> list)
        {
            var listType = list.GetType();
            var addMethod = listType.GetMethod("Add");
            var itemType = listType.GenericTypeArguments[0];
            var itemProperties = itemType.GetProperties();

            var action = new Action<object[]>((values) =>
            {
                var item = Activator.CreateInstance(itemType);

                for(var i = 0; i < values.Length; i++)
                {
                    itemProperties[i].SetValue(item, values[i]);
                }

                addMethod.Invoke(list, new []{item});
            });

            return action;
        }

        /// <summary>
        /// Creates a type based on the property/type values specified in the properties
        /// </summary>
        /// <param name="properties"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static Type CreateDynamicType(IEnumerable<DynamicTypeProperty> properties)
        {
            StringBuilder classCode = new StringBuilder();

            // Generate the class code
            classCode.AppendLine("using System;");
            classCode.AppendLine("namespace Dexih {");
            classCode.AppendLine("public class DynamicClass {");

            foreach (var property in properties)
            {
                classCode.AppendLine($"public {property.Type.Name} {property.Name} {{get; set; }}");
            }
            classCode.AppendLine("}");
            classCode.AppendLine("}");

            var syntaxTree = CSharpSyntaxTree.ParseText(classCode.ToString());

            var references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
                MetadataReference.CreateFromFile(typeof(DictionaryBase).GetTypeInfo().Assembly.Location)
            };

            var compilation = CSharpCompilation.Create("DynamicClass" + Guid.NewGuid() + ".dll",
                syntaxTrees: new[] {syntaxTree},
                references: references,
                options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            using (var ms = new MemoryStream())
            {
                var result = compilation.Emit(ms);

                if (!result.Success)
                {
                    var failures = result.Diagnostics.Where(diagnostic =>
                        diagnostic.IsWarningAsError ||
                        diagnostic.Severity == DiagnosticSeverity.Error);

                    var message = new StringBuilder();

                    foreach (var diagnostic in failures)
                    {
                        message.AppendFormat("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
                    }

                    throw new Exception($"Invalid property definition: {message}.");
                }
                else
                {

                    ms.Seek(0, SeekOrigin.Begin);
                    var assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(ms);
                    var dynamicType = assembly.GetType("Dexih.DynamicClass");
                    return dynamicType;
                }
            }
        }
    }

দুর্দান্ত টুকরো কোড। একসাথে একাধিক রেকর্ড যুক্ত করার জন্য গতিশীল তালিকায় অ্যাডরেঞ্জও ব্যবহার করা সম্ভব হবে?
রিকিট্যাড

2

আপনি ডায়নামিক মডিউল এবং ক্লাসগুলি ব্যবহার করতে পারেন যা কাজটি করতে পারে। একমাত্র অসুবিধা হ'ল এটি অ্যাপ ডোমেনে লোড থাকে। কিন্তু .NET ফ্রেমওয়ার্কের সংস্করণটি ব্যবহার হচ্ছে, এটি পরিবর্তন হতে পারে। .NET 4.0 সংগ্রহযোগ্য গতিশীল সমাবেশগুলি সমর্থন করে এবং তাই আপনি গতিশীলভাবে ক্লাস / প্রকার পুনরায় তৈরি করতে পারেন।


2

কি দারুন! এই উত্তরের জন্য আপনাকে ধন্যবাদ! আমি আপনার সাথে ভাগ করে নেওয়ার একটি "ডেটাটেবল টু জসন" রূপান্তরকারী তৈরি করতে এর সাথে কিছু বৈশিষ্ট্য যুক্ত করেছি।

    Public Shared Sub dt2json(ByVal _dt As DataTable, ByVal _sb As StringBuilder)
    Dim t As System.Type

    Dim oList(_dt.Rows.Count - 1) As Object
    Dim jss As New JavaScriptSerializer()
    Dim i As Integer = 0

    t = CompileResultType(_dt)

    For Each dr As DataRow In _dt.Rows
        Dim o As Object = Activator.CreateInstance(t)

        For Each col As DataColumn In _dt.Columns
            setvalue(o, col.ColumnName, dr.Item(col.ColumnName))
        Next

        oList(i) = o
        i += 1
    Next

    jss = New JavaScriptSerializer()
    jss.Serialize(oList, _sb)


End Sub

এবং "কম্পাইলারসাল্ট টাইপ" সাব এ, আমি এটি পরিবর্তন করেছি:

    For Each column As DataColumn In _dt.Columns
        CreateProperty(tb, column.ColumnName, column.DataType)
    Next


Private Shared Sub setvalue(ByVal _obj As Object, ByVal _propName As String, ByVal _propValue As Object)
    Dim pi As PropertyInfo
    pi = _obj.GetType.GetProperty(_propName)
    If pi IsNot Nothing AndAlso pi.CanWrite Then
        If _propValue IsNot DBNull.Value Then
            pi.SetValue(_obj, _propValue, Nothing)

        Else
            Select Case pi.PropertyType.ToString
                Case "System.String"
                    pi.SetValue(_obj, String.Empty, Nothing)
                Case Else
                    'let the serialiser use javascript "null" value.
            End Select

        End If
    End If

End Sub

0

আপনি System.Runtime.Remoting.Proxies.RealProxy ব্যবহার করতে পারেন। এটি আপনাকে নিম্ন স্তরের সমাবেশের ধরণের স্টাফের চেয়ে "সাধারণ" কোড ব্যবহার করার অনুমতি দেবে।

একটি ভাল উদাহরণের জন্য এই প্রশ্নের রিয়েলপ্রক্সির উত্তর দেখুন:

আমি কীভাবে সি # তে কোনও মেথড কলকে বাধা দেব?


-1

Runtime Code Generation with JVM and CLR - পিটার সিস্টফট

এই ধরণের প্রোগ্রামিংয়ে সত্যই আগ্রহী ব্যক্তিদের জন্য কাজ করুন।

আপনার জন্য আমার পরামর্শটি হ'ল যদি আপনি কিছু স্ট্রিং এড়ানোর চেষ্টা করার ঘোষণা করেন তবে আপনার যদি ক্লাস ফিল্ড থাকে তবে ক্লাস সিস্টেম ব্যবহার করা ভাল । স্ট্রিংয়ের চেয়ে ক্ষেত্রের ধরন সংরক্ষণের জন্য টাইপ করুন। এবং সৃষ্টির পরিবর্তে সর্বোত্তম সমাধানের জন্য নতুন ক্লাসগুলি নতুন নতুন তৈরির পরিবর্তে ফিল্ডইনফো তৈরি করা হয়েছে তাদের ব্যবহার করার চেষ্টা করুন ।


2
লিঙ্কটি মারা গেছে: -1
গ্লেন স্লেডেন

গ্লেন: একটি দ্রুত গুগল
Andreas Pardeike

@ আন্দ্রেস পার্দিকে ধন্যবাদ, আমি নিবন্ধটি এটি মেরামত করেছি।
গ্লেন স্লেডেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.