আমি কীভাবে গতিশীল সি # কোডটি মূল্যায়ন করতে পারি?


95

আমি eval("something()");জাভাস্ক্রিপ্টে গতিশীলভাবে কোডটি কার্যকর করতে একটি করতে পারি । আমার কাছে সি # তে একই জিনিস করার কোনও উপায় আছে কি?

আমি যা করার চেষ্টা করছি তার একটি উদাহরণ হ'ল আমার একটি পূর্ণসংখ্যার ভেরিয়েবল আছে (বলুন i) এবং নামগুলি সহ আমার একাধিক সম্পত্তি রয়েছে: "সম্পত্তি 1", "সম্পত্তি 2", "সম্পত্তি3" ইত্যাদি Now এখন, আমি কিছু অপারেশন করতে চাই "সম্পত্তি আমি " সম্পত্তি উপর নির্ভর করে i

এটি জাভাস্ক্রিপ্ট সহ সত্যিই সহজ। সি # দিয়ে এটি করার কোনও উপায় আছে কি?



4
সি # কল করুন ইস্ত্রিপিথনের ইভাল। আমি এটি সি # 4.0 এ চেষ্টা করেছি। সি # 2.0 এর সাথে কোনও অভিজ্ঞতা নেই
পিটার লং

@ পিটার লং, আমি কোথায় আয়রন পাইথনের বিস্তারে ডকুমেন্টেশন পেতে পারি?
স্মার্টকাভম্যান

@ অডিপগুপ্ত আমি জানি যে এই প্রশ্নোত্তরটি বেশ তারিখের, তবে আমি সবেমাত্র একটি ভিডিও প্লেলিস্ট প্রকাশ করেছি যা ডেভিড ইকার্ডির উত্তরে বর্ণিত বর্ণনার মতো পুরোপুরি শোনাচ্ছে। এটি নাটকীয়ভাবে পৃথক, এবং সম্ভবত চেক আউট মূল্যবান।
রিক রিগস

উত্তর:


49

দুর্ভাগ্যক্রমে, সি # এর মতো গতিময় ভাষা নয়।

যাইহোক, আপনি যা করতে পারেন তা হল একটি # # উত্স কোড ফাইল তৈরি করা, যা ক্লাস এবং সমস্ত কিছুর সাথে পূর্ণ, এবং এটি সি # এর জন্য কোডডম সরবরাহকারীর মাধ্যমে চালিত করে এবং এটি একটি অ্যাসেমব্লিতে সংকলন করে, এবং তারপরে এক্সিকিউট করে।

এমএসডিএন-এ এই ফোরামের পোস্টটিতে কিছুটা পৃষ্ঠা কোডের উদাহরণ কোড সহ একটি উত্তর রয়েছে:
একটি স্ট্রিং থেকে বেনামী পদ্ধতি তৈরি করুন?

আমি খুব কমই বলব এটি খুব ভাল সমাধান, তবে যাইহোক এটি সম্ভব is

আপনি কি স্ট্রিং মধ্যে কোড আশা করতে যাচ্ছেন? যদি এটি বৈধ কোডের একটি সামান্য উপসেট হয়, উদাহরণস্বরূপ কেবল গণিতের এক্সপ্রেশন থাকে তবে এটি অন্যান্য বিকল্পের উপস্থিতি হতে পারে।


সম্পাদনা : আচ্ছা, এটি আমাকে প্রথমে প্রশ্নগুলি ভালভাবে পড়তে শেখায়। হ্যাঁ, প্রতিবিম্ব এখানে আপনাকে কিছু সহায়তা দিতে সক্ষম হবে।

যদি আপনি স্ট্রিংটি দ্বারা বিভক্ত করেন; প্রথমত, পৃথক বৈশিষ্ট্য পেতে, আপনি একটি শ্রেণীর জন্য একটি নির্দিষ্ট সম্পত্তির জন্য সম্পত্তি আইইনফো অবজেক্ট পেতে নিম্নলিখিত কোডটি ব্যবহার করতে পারেন, এবং তারপরে একটি নির্দিষ্ট অবজেক্টটি ম্যানিপুলেট করতে সেই অবজেক্টটি ব্যবহার করতে পারেন।

String propName = "Text";
PropertyInfo pi = someObject.GetType().GetProperty(propName);
pi.SetValue(someObject, "New Value", new Object[0]);

লিঙ্ক: প্রপার্টিআইএনফো.সেটভ্যালু পদ্ধতি


যদি getProperty এর এক্স, ওয়াই প্যারামের সাথে কোন ফাংশন থাকতে হয় ?, মানে পাঠ্য (1,2)?
ব্যবহারকারী 1735921

@ ব্যবহারকারী 1735921 তারপরে আপনাকে এর GetMethod(methodName)পরিবর্তে প্যারামিটারের মানগুলি বিশ্লেষণ করতে হবে এবং প্রতিবিম্বটি ব্যবহার করে পদ্ধতিটি কল করতে হবে।
লাসে ভি কার্লসেন

টাইপফ (অবজেক্টটাইপ) হ'ল কিছু অবজেক্ট.গেটটাইপ ()
থিয়াগো

37

রোজলিন স্ক্রিপ্টিং এপিআই ব্যবহার করে (আরও নমুনা এখানে ):

// add NuGet package 'Microsoft.CodeAnalysis.Scripting'
using Microsoft.CodeAnalysis.CSharp.Scripting;

await CSharpScript.EvaluateAsync("System.Math.Pow(2, 4)") // returns 16

আপনি যে কোনও কোডের টুকরোটি চালাতে পারেন:

var script = await CSharpScript.RunAsync(@"
                class MyClass
                { 
                    public void Print() => System.Console.WriteLine(1);
                }")

এবং আগের রানগুলিতে উত্পন্ন কোডটি উল্লেখ করুন:

await script.ContinueWithAsync("new MyClass().Print();");

14

আসলে তা না. আপনি যা চান তা অর্জন করতে আপনি প্রতিবিম্ব ব্যবহার করতে পারেন তবে এটি জাভাস্ক্রিপ্টের মতো প্রায় সহজ হবে না। উদাহরণস্বরূপ, আপনি যদি কোনও জিনিসের ব্যক্তিগত ক্ষেত্র সেট করতে চান তবে আপনি এই ফাংশনটি ব্যবহার করতে পারেন:

protected static void SetField(object o, string fieldName, object value)
{
   FieldInfo field = o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
   field.SetValue(o, value);
}

11

এটি সি # এর অধীনে একটি ইভাল ফাংশন। আমি এটিকে স্ট্রিং থেকে বেনামে ফাংশন (ল্যাম্বডা এক্সপ্রেশন) রূপান্তর করতে ব্যবহার করেছি। সূত্র: http://www.codeproject.com/KB/cs/evalcscode.aspx

public static object Eval(string sCSCode) {

  CSharpCodeProvider c = new CSharpCodeProvider();
  ICodeCompiler icc = c.CreateCompiler();
  CompilerParameters cp = new CompilerParameters();

  cp.ReferencedAssemblies.Add("system.dll");
  cp.ReferencedAssemblies.Add("system.xml.dll");
  cp.ReferencedAssemblies.Add("system.data.dll");
  cp.ReferencedAssemblies.Add("system.windows.forms.dll");
  cp.ReferencedAssemblies.Add("system.drawing.dll");

  cp.CompilerOptions = "/t:library";
  cp.GenerateInMemory = true;

  StringBuilder sb = new StringBuilder("");
  sb.Append("using System;\n" );
  sb.Append("using System.Xml;\n");
  sb.Append("using System.Data;\n");
  sb.Append("using System.Data.SqlClient;\n");
  sb.Append("using System.Windows.Forms;\n");
  sb.Append("using System.Drawing;\n");

  sb.Append("namespace CSCodeEvaler{ \n");
  sb.Append("public class CSCodeEvaler{ \n");
  sb.Append("public object EvalCode(){\n");
  sb.Append("return "+sCSCode+"; \n");
  sb.Append("} \n");
  sb.Append("} \n");
  sb.Append("}\n");

  CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
  if( cr.Errors.Count > 0 ){
      MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, 
         "Error evaluating cs code", MessageBoxButtons.OK, 
         MessageBoxIcon.Error );
      return null;
  }

  System.Reflection.Assembly a = cr.CompiledAssembly;
  object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");

  Type t = o.GetType();
  MethodInfo mi = t.GetMethod("EvalCode");

  object s = mi.Invoke(o, null);
  return s;

}

4
উফফফফ, আমি টাইপো সংশোধন করেছি (লাম্বাডা => ল্যাম্বদা)। আমি জানতাম না যে গানটিকে লাম্বাডা বলা হয় তাই এটি একটি অনিচ্ছাকৃত। ;)
লার্গো

এই উত্তরটি কেন কম ভোট পাবে তা আমি বুঝতে পারি না। এটা খুব দরকারী।
মোজাফফার গালাতা

9

ডায়নামিক এক্সপ্রেসো একটি ওপেন সোর্স প্রকল্প লিখেছি , যা সি # সিনট্যাক্স ব্যবহার করে লিখিত পাঠ্য এক্সপ্রেশনকে ডেলিগেটস (বা এক্সপ্রেশন ট্রি) এ রূপান্তর করতে পারে। সংকলন বা প্রতিবিম্ব ব্যবহার না করে এক্সপ্রেশনগুলি পার্স এবং এক্সপ্রেশন ট্রিগুলিতে রূপান্তরিত হয় ।

আপনি যেমন কিছু লিখতে পারেন:

var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");

বা

var interpreter = new Interpreter()
                      .SetVariable("service", new ServiceExample());

string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";

Lambda parsedExpression = interpreter.Parse(expression, 
                          new Parameter("x", typeof(int)));

parsedExpression.Invoke(5);

আমার কাজ স্কট গু নিবন্ধের উপর ভিত্তি করে http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1- using-the-linq-dynamic-query-library.aspx ।


7

যে সব অবশ্যই কাজ করবে। ব্যক্তিগতভাবে, এই বিশেষ সমস্যার জন্য, আমি সম্ভবত কিছুটা ভিন্ন পদ্ধতির গ্রহণ করব। এরকম কিছু হতে পারে:

class MyClass {
  public Point point1, point2, point3;

  private Point[] points;

  public MyClass() {
    //...
    this.points = new Point[] {point1, point2, point3};
  }

  public void DoSomethingWith(int i) {
    Point target = this.points[i+1];
    // do stuff to target
  }
}

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

আমি বুঝতে পেরেছিলাম যে এটি ঠিক প্রশ্ন নয়, তবে প্রশ্নের বেশ ভাল উত্তর দেওয়া হয়েছে এবং আমি ভেবেছিলাম যে কোনও বিকল্প পদ্ধতির সাহায্য হতে পারে।


5

আপনি এখন সি # স্টেটমেন্টগুলি কার্যকর করতে চাইলে আমি এখন তা করি না তবে আপনি ইতিমধ্যে সি # 2.0 তে জাভাস্ক্রিপ্টের বিবৃতি কার্যকর করতে পারেন। মুক্ত উত্স গ্রন্থাগার জিন্ট এটি করতে সক্ষম। এটি নেট। এর জন্য একটি জাভাস্ক্রিপ্ট দোভাষী। একটি জাভাস্ক্রিপ্ট প্রোগ্রাম পাস করুন এবং এটি আপনার আবেদনের ভিতরে চলবে। এমনকি আপনি সি # অবজেক্টকে আর্গুমেন্ট হিসাবে পাস করতে এবং এটিতে অটোমেশন করতে পারেন।

এছাড়াও আপনি যদি কেবল নিজের বৈশিষ্ট্যগুলিতে অভিব্যক্তিটি মূল্যায়ন করতে চান তবে NCalc এ চেষ্টা করুন ।


4

আপনি সম্পত্তি পেতে এবং এটি প্রার্থনা করতে প্রতিবিম্ব ব্যবহার করতে পারেন। এটার মতো কিছু:

object result = theObject.GetType().GetProperty("Property" + i).GetValue(theObject, null);

অর্থাৎ, সম্পত্তিটির যে অবজেক্টটি রয়েছে তাকে ধরে নিয়ে যাওয়াটিকে "দ্য অবজেক্ট" বলা হয় :)


2

আপনি কোনও ওয়েব ব্রাউজার কার্যকর করতে পারেন, তারপরে জাভাস্ক্রিপ্ট থাকা একটি এইচটিএমএল-ফাইল লোড করুন।

তারপরে আপনি document.InvokeScriptএই ব্রাউজারে মেথডের জন্য যান । ইভাল ফাংশনটির রিটার্ন ভ্যালু ক্যাচ করা যায় এবং আপনার প্রয়োজনীয় সমস্ত কিছুতে রূপান্তর করা যায়।

আমি বেশ কয়েকটি প্রকল্পে এটি করেছি এবং এটি পুরোপুরি কার্যকর হয়।

আশা করি এটা সাহায্য করবে


0

আপনি এটি একটি প্রোটোটাইপ ফাংশন দিয়ে করতে পারেন:

void something(int i, string P1) {
    something(i, P1, String.Empty);
}

void something(int i, string P1, string P2) {
    something(i, P1, P2, String.Empty);
}

void something(int i, string P1, string P2, string P3) {
    something(i, P1, P2, P3, String.Empty);
}

এবং তাই ...



0

গতিশীলভাবে কোড সংকলন ও সম্পাদন করার কাজটি সহজ করার জন্য আমি একটি প্যাকেজ, শার্পবাইট.ডায়নামিক লিখেছি । কোডটি এখানে বিস্তারিত হিসাবে এক্সটেনশন পদ্ধতিগুলি ব্যবহার করে যে কোনও প্রসঙ্গের অবজেক্টে আহ্বান করা যেতে পারে ।

উদাহরণ স্বরূপ,

someObject.Evaluate<int>("6 / {{{0}}}", 3))

ফেরত 3;

someObject.Evaluate("this.ToString()"))

প্রসঙ্গ বস্তুর স্ট্রিং প্রতিনিধিত্ব প্রদান করে;

someObject.Execute(@
"Console.WriteLine(""Hello, world!"");
Console.WriteLine(""This demonstrates running a simple script"");
");

এই বিবৃতিগুলি স্ক্রিপ্ট ইত্যাদি হিসাবে চালায়

এক্সিকিউটেবলগুলি সহজেই কারখানার পদ্ধতি ব্যবহার করে অর্জন করা যায়, যেমন এখানে উদাহরণে দেখা গেছে - আপনার প্রয়োজন সমস্ত উত্সের কোড এবং কোনও প্রত্যাশিত নামযুক্ত প্যারামিটারের তালিকা (টোকেনগুলি ট্রিপল-ব্র্যাকেট স্বরলিপি ব্যবহার করে এম্বেড করা হয়েছে, যেমন {{{0}} string, স্ট্রিংয়ের সাথে সংঘর্ষ এড়ানোর জন্য For ফর্ম্যাট () পাশাপাশি হ্যান্ডলবার্সের মতো সিনট্যাক্স):

IExecutable executable = ExecutableFactory.Default.GetExecutable(executableType, sourceCode, parameterNames, addedNamespaces);

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

একটি ইতিমধ্যে সংকলিত স্ক্রিপ্ট বা বিবৃতি কার্যকর করার ওভারহেড তুলনামূলকভাবে কম, খুব ভাল মাঝারি হার্ডওয়্যারে একটি মাইক্রোসেকেন্ডের অধীনে, এবং ইতিমধ্যে সংকলিত স্ক্রিপ্ট এবং এক্সপ্রেশনগুলি পুনরায় ব্যবহারের জন্য ক্যাশে করা হয়।


0

আমি এর নাম অনুসারে কোনও কাঠামোর (শ্রেণি) সদস্যের একটি মূল্য পাওয়ার চেষ্টা করছিলাম। কাঠামোটি গতিশীল ছিল না। অবশেষে এটি না পাওয়া পর্যন্ত সমস্ত উত্তর কার্যকর হয়নি:

public static object GetPropertyValue(object instance, string memberName)
{
    return instance.GetType().GetField(memberName).GetValue(instance);
}

এই পদ্ধতিটি তার নাম অনুসারে সদস্যের মান প্রদান করবে। এটি নিয়মিত কাঠামো (শ্রেণি) উপর কাজ করে।


0

আপনি heleonix.Fir নির্বাচন লাইব্রেরি পরীক্ষা করতে পারেন । এটি নেস্টেড সদস্যবৃন্দ সহ সদস্যদের ডায়নামিকভাবে / সেট / আবেদনের জন্য পদ্ধতি সরবরাহ করে বা কোনও সদস্য যদি স্পষ্টভাবে সংজ্ঞায়িত হয় তবে আপনি একটি গেটর / সেটার তৈরি করতে পারেন (একটি প্রতিনিধিতে সংকলিত লাম্বদা) প্রতিবিম্বের চেয়ে দ্রুততর:

var success = Reflector.Set(instance, null, $"Property{i}", value);

বা বৈশিষ্ট্যের সংখ্যা যদি অন্তহীন না হয় তবে আপনি সেটারগুলি তৈরি করতে পারেন এবং সেগুলি চালাবেন (সেটারগুলি প্রতিনিধি সংকলিত হওয়ার কারণে সেটারগুলি দ্রুততর হয়):

var setter = Reflector.CreateSetter<object, object>($"Property{i}", typeof(type which contains "Property"+i));
setter(instance, value);

সেটারগুলি ধরণের হতে পারে Action<object, object>তবে রানটাইমগুলিতে উদাহরণগুলি পৃথক হতে পারে, তাই আপনি সেটারগুলির তালিকা তৈরি করতে পারেন।


-1

দুর্ভাগ্যক্রমে, সি # এর কাছে যা চাইছেন ঠিক তেমন করার জন্য কোনও দেশীয় সুবিধা নেই।

তবে, আমার সি # ইভাল প্রোগ্রামটি সি # কোড মূল্যায়নের জন্য অনুমতি দেয়। এটি রানটাইমে সি # কোড মূল্যায়নের জন্য সরবরাহ করে এবং অনেক সি # বিবৃতি সমর্থন করে। আসলে, এই কোডটি কোনও নেট প্রকল্পের মধ্যে ব্যবহারযোগ্য, তবে এটি সি # সিনট্যাক্স ব্যবহারের মধ্যে সীমাবদ্ধ। অতিরিক্ত তথ্যের জন্য আমার ওয়েবসাইট, http://csharp-eval.com এ দেখুন।


একটি সময়ে কটাক্ষপাত আছে Roslyn স্ক্রিপ্টিং এপিআই
AlexMelw

-9

সঠিক উত্তরটি হ'ল মেমারি ব্যবহারের পরিমাণ কম রাখার জন্য আপনাকে সমস্ত ফলাফলের ক্যাশে করা দরকার।

একটি উদাহরণ এটি দেখতে হবে

TypeOf(Evaluate)
{
"1+1":2;
"1+2":3;
"1+3":5;
....
"2-5":-3;
"0+0":1
} 

এবং এটি একটি তালিকায় যুক্ত করুন

List<string> results = new List<string>();
for() results.Add(result);

আইডি সংরক্ষণ করুন এবং কোড ব্যবহার করুন

আশাকরি এটা সাহায্য করবে


5
কেউ লুকিং সঙ্গে মূল্যায়ন বিভ্রান্ত। যদি আপনি সমস্ত সম্ভাব্য প্রোগ্রামগুলি জানেন (আমি মনে করি এটি কমপক্ষে এনপি-হার্ড) ... এবং আপনার সম্ভাব্য সকল ফলাফলের পূর্বনির্ধারিত করার জন্য একটি সুপারমেশিন রয়েছে ... এবং কোনও পার্শ্ব প্রতিক্রিয়া / বাহ্যিক ইনপুট নেই ... হ্যাঁ, এই ধারণা তাত্ত্বিকভাবে কাজ করে । কোড এক বড় বাক্যগঠন ত্রুটি, যদিও
sehe
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.