web-dev-qa-db-ja.com

C#Eval()サポート

正確なメンバーパスのテキストステートメントがある間、実行時にオブジェクトの値を評価する必要があります。例:myobject.firstMember.secondMember [3] .text
私たちはこのテキストステートメントを正規表現を使用して解析し、リフレクションを使用してテキスト値を評価することを考えましたが、その前に、C#が何らかのeval機能をサポートしているかどうか疑問に思いますか?自分で解析する必要はありません。マイクロソフトはこれをイミディエイトウィンドウまたはウォッチウィンドウでどのように実行しますか?

どうもありがとうございます、

アディバルダ

19
Adi Barda

おそらく最も簡単な方法は、System.Web.UIの DataBinder.Eval を使用することです。

var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
17
Alex Yakunin

C#構文を使用して記述されたテキスト式をデリゲート(または式ツリー)に変換できるオープンソースプロジェクト Dynamic Expresso を作成しました。式は、コンパイルまたはリフレクションを使用せずに解析されて 式ツリー に変換されます。

あなたは次のようなものを書くことができます:

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

17
Davide Icardi

将来(5.0前後)、「サービスとしてのコンパイラ」がこれを実行できるようになる可能性があります。実際には、「mono」を使用して、これの多くを実行できる可能性があります( CsharpRepl および Mono.CSharp を参照)-ただし、 Evaluate )でローカル変数などを使用できるようにするためのコンテキストについて詳しく説明しますが、現在のMS .NET製品ではこれに対するサポートはありません。

とりあえず、データバインディングコードの多くが行うようなことを行う必要があります... "。"などのトークンで分割します。リフレクションを使用します。厳密に言うと、バインディングコードは直接反射ではなく実際にTypeDescriptor/PropertyDescriptorを使用しますが、効果は同じです。

8
Marc Gravell

やや重いアプローチですが、C#CodeDomを使用して、そのコード行のみを含むメソッドを含む新しい新しいアセンブリを発行できます。

これは他のいくつかの提案よりもはるかに強引であると私は認めますが、一方で、C#パーサーに重い処理を行わせるため、有効なC#である限り、投げたすべてのものを処理できるはずです。 。

そのルートをたどる場合は、放出されたアセンブリを再度アンロードできることを確認する必要もあります。そのため、AppDomainの作成とアンロードが必要になる場合があります。

私は上記の手法をうまく実装して使用しました。一方、 DynamicMethod を使用できる場合は、はるかに軽量になります。ただし、その方法を試したことがないので、C#リテラルを使用してDynamicMethodの本体を実装できるかどうかはわかりません。

1
Mark Seemann

実際、Windows Workflow Foundationの式評価およびルールエンジン機能は、このようなことを行うことができます。 Windows Workflow Foundationルールエンジンの概要 を参照してください。

これらのコンポーネントの興味深い点の1つは、独自のアプリケーションで設計時コンポーネントをホストして、独自のカスタムクラスのコンテキストで動作するルールや式のセットを設計できるように設計されていることです。たとえば、 "myObject"に対する式を設計するように指示すると、テキストプロパティを持つ型を生成するインデクサーを持つsecondMemberを持つfirstMemberがあることがわかります。実行時にデザイナーを使用する必要なく、式とルールをXMLとして永続化し、実行時に読み取ることができます。

特に External RuleSet Toolkit Sample をご覧ください。

1
John Saunders

いつでも私の軽量C#評価プログラムを試すことができます。 C#言語の実質的なサブセットを動的メソッドにコンパイルします。私のGitHubリポジトリの詳細 DavidWynne/CSharpEval

1
David Wynne

残念ながら、C#には、ユーザーが求めていることを正確に実行するためのネイティブ機能がありません。

ただし、私のC#evalプログラムでは、C#コードを評価できます。実行時にC#コードを評価し、「myobject.firstMember.secondMember [3] .text」のような式を含む多くのC#ステートメントをサポートします。実際、このコードは.NETプロジェクト内で使用できますが、C#構文の使用に限定されています。詳細については、私のウェブサイト http://csharp-eval.com をご覧ください。

1
xnaterm

私の知る限り、そのような組み込みの評価関数はありません。 Regex + Reflectionを使用する必要があります。 Visual Studioも同じことをしていると思います。

0
Vilx-

これは、動的にネストされたプロパティを見つけるために私が使用しているものと似ています。インデクサーのロジックを追加する必要があります...そして、いくつかの追加のチェック...私の呼び出しメソッドでnull /エラーをキャッチしています...

 public static object FindDottedProperty(this object input、string propertyName)
 {
 if(input == null)
 return null; 
 
 if(string.IsNullOrEmpty(propertyName))
 return null; 
 
 Queue props = new Queue(propertyName.Split( '。')); 
 if(props.Count == 0)return null; 
 
 //入力オブジェクトから開始し、そこからプロパティスタックをロールアウトします。
オブジェクトret = input; 
 while(props.Count> 0)
 {
 var prop = props.Dequeue(); 
 if(string.IsNullOrEmpty(prop))がnullを返す; 
 
/***ここにインデクサーロジックを追加***/
 
 //現在の名前付きアイテムに基づいてプロパティの値を取得
 ret = ret。 GetType()。GetProperty(prop).GetValue(ret、null); 
 
 if(null.Equals(ret))がnullを返す; 
} 
 
 //検索された値を返す
 return ret; 
} 
0
Tracker1