রানটাইমের সময় প্রাপ্ত টাইপগুলি থেকে গতিশীলভাবে একটি বর্গ তৈরি করা


20

সি # (বা অন্য কোনও ভাষায়) নিম্নলিখিতগুলি করা কি সম্ভব?

  1. আমি একটি ডাটাবেস থেকে ডেটা আনছি। রান সময়ে আমি কলামগুলি আনা কলামের সংখ্যা এবং ডেটা ধরণের সংখ্যা গণনা করতে পারি।

  2. পরবর্তী আমি ক্ষেত্র হিসাবে এই ডেটা ধরণের একটি শ্রেণি "উত্পন্ন" করতে চাই। আমি সংগ্রহটিতে যে সমস্ত রেকর্ড পেয়েছি সেগুলিও সঞ্চয় করতে চাই।

সমস্যাটি হ'ল আমি রানটাইমে 1 এবং 2 পদক্ষেপ দুটিই করতে চাই

এটা কি সম্ভব? আমি বর্তমানে সি # ব্যবহার করছি তবে আমার প্রয়োজন হলে আমি অন্য কিছুতে স্থানান্তর করতে পারি।


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

নিশ্চিত করুন যে আপনি কাজ রব Conery করেছিল কটাক্ষপাত আছে কি না নিশ্চিত dynamic: গুরুভার মধ্যে blog.wekeroad.com/helpy-stuff/and-i-shall-call-it-massive
রবার্ট হার্ভে

1
পাইথন গতিশীল শ্রেণীর ঘোষণার অনুমতি দেয় এবং বাস্তবে এটি সাধারণ। 2001 এর কাছাকাছি থেকে ডেভিড মের্টজের একটি টিউটোরিয়াল ছিল (আমি এটি সন্ধান করেছি তবে সঠিক লিঙ্কটি খুঁজে পাইনি)। এটা সোজা।
smci

@ রবার্টহার্ভে আপনার ভাগ করা লিঙ্কটি মারা গেছে is আপনি কি জানেন আমি এটি কোথায় পাব?
জোজে

1
যদিও প্রযুক্তিগতভাবে সম্ভব, আমাকে এটি করার মান নিয়ে প্রশ্ন করতে হবে। শক্তিশালী টাইপিং এবং ক্লাসগুলির মূল বিষয়টি যাতে সংকলনের সময় আপনি বাক্য গঠন ত্রুটিগুলি পরীক্ষা করতে ক্লাসের তথ্য ব্যবহার করতে সক্ষম হন (গতিশীল JITers এর নতুন প্রজন্ম এটি ছাড়াই অনুকূলিত করতে পারে)। স্পষ্টতই
দৃ strongly়ভাবে

উত্তর:


28

কোডডম ব্যবহার করুন। শুরু করার জন্য এখানে কিছু

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.CodeDom;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string className = "BlogPost";

            var props = new Dictionary<string, Type>() {
                { "Title", typeof(string) },
                { "Text", typeof(string) },
                { "Tags", typeof(string[]) }
            };

            createType(className, props);
        }

        static void createType(string name, IDictionary<string, Type> props)
        {
            var csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v4.0" } });
            var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll"}, "Test.Dynamic.dll", false);
            parameters.GenerateExecutable = false;

            var compileUnit = new CodeCompileUnit();
            var ns = new CodeNamespace("Test.Dynamic");
            compileUnit.Namespaces.Add(ns);
            ns.Imports.Add(new CodeNamespaceImport("System"));

            var classType = new CodeTypeDeclaration(name);
            classType.Attributes = MemberAttributes.Public;
            ns.Types.Add(classType);

            foreach (var prop in props)
            {
                var fieldName = "_" + prop.Key;
                var field = new CodeMemberField(prop.Value, fieldName);
                classType.Members.Add(field);

                var property = new CodeMemberProperty();
                property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                property.Type = new CodeTypeReference(prop.Value);
                property.Name = prop.Key;
                property.GetStatements.Add(new CodeMethodReturnStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName)));
                property.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), fieldName), new CodePropertySetValueReferenceExpression()));
                classType.Members.Add(property);
            }

            var results = csc.CompileAssemblyFromDom(parameters,compileUnit);
            results.Errors.Cast<CompilerError>().ToList().ForEach(error => Console.WriteLine(error.ErrorText));
        }
    }
}

এটি এই ক্লাসে এটি একটি সমাবেশ 'টেস্ট.ডায়নামিক.ডিল' তৈরি করে

namespace Test.Dynamic
{
    public class BlogPost
    {
        private string _Title;
        private string _Text;
        private string[] _Tags;

        public string Title
        {
            get
            {
                return this._Title;
            }
            set
            {
                this._Title = value;
            }
        }
        public string Text
        {
            get
            {
                return this._Text;
            }
            set
            {
                this._Text = value;
            }
        }
        public string[] Tags
        {
            get
            {
                return this._Tags;
            }
            set
            {
                this._Tags = value;
            }
        }
    }
}

আপনি সি # এর গতিশীল বৈশিষ্ট্যগুলিও ব্যবহার করতে পারেন

ডায়নামিক এন্টিটি ক্লাস, রানটাইমের সময় কিছু তৈরি করার দরকার নেই

public class DynamicEntity : DynamicObject
{
    private IDictionary<string, object> _values;

    public DynamicEntity(IDictionary<string, object> values)
    {
        _values = values;
    }
    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _values.Keys;
    }
    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_values.ContainsKey(binder.Name))
        {
            result = _values[binder.Name];
            return true;
        }
        result = null;
        return false;
    }
}

এবং এটি ব্যবহার করুন

var values = new Dictionary<string, object>();
values.Add("Title", "Hello World!");
values.Add("Text", "My first post");
values.Add("Tags", new[] { "hello", "world" });

var post = new DynamicEntity(values);

dynamic dynPost = post;
var text = dynPost.Text;

6

হ্যাঁ, আপনি এটি করতে প্রতিচ্ছবি ইমিট ব্যবহার করতে পারেন । ম্যানিংয়ের কাছে এটির মতো একটি দুর্দান্ত বই বের হচ্ছে যা দেখায়: নেট .মেট

বিটিডাব্লু: কেন কেবল অভিধান যুক্ত বা একই জাতীয় ক্ষেত্রের নামগুলি ক্ষেত্রের নামগুলির সাথে সংরক্ষণের জন্য একই জাতীয় তালিকা ব্যবহার করবেন না?


1
মেটা-প্রোগ্রামিং রেফারেন্সের জন্য আপনাকে ধন্যবাদ। আমি খুঁজে পাওয়া আরও কয়েকটি এখানে রয়েছে: vslive.com/Blogs/News- এবং- Tips
লিও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.