2009-06-21 5 views
16

myobject.firstMember.secondMemberは、[3]私たちは考え
を.TEXT regexを使ってこのテキスト文を解析し、反射を使ってテキスト値を評価しますが、私はそれを行う前にC#が何らかの種類のevalの能力をサポートしているのだろうか?私たち自身を解析する必要はありません。マイクロソフトはどのようにして直下のウィンドウやウォッチウィンドウでこれを行うのですか?C#エバール()のサポート

おかげで、あなたは非常に多くの、

アディ・バルダ

答えて

12

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

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

そのような内蔵の評価機能はありません私の知る限り。あなたはRegex + Reflectionのやり方をしなければならないでしょう。私はまた、Visual Studioも同じことをやっていると思います。

8

将来的には(約5.0タイムフレーム)、「サービスとしてのコンパイラ」がこれを行うことができます。実際には、 "モノ"で多くのことを行うことができます(CsharpReplMono.CSharpを参照してください)。Evaluateでローカル変数などを使用できるようにするためには、 - しかし、現在のMS .NET製品では、これに対するサポートはありません。

今のところ、多くのデータバインディングコードのように、 "。"などのトークンで分割しなければなりません。反射を使用します。厳密に言えば、バインディングコードは実際には直接反射ではなくTypeDescriptor/PropertyDescriptorを使用しますが、効果は同じです。

1

多少重いアプローチですが、C#CodeDomを使用して、そのコード行だけのメソッドを含む新しいアセンブリを新規に生成できます。

これは他のいくつかの提案よりもはるかに重いですが、一方ではC#パーサーが重い持ち上げをするようにしていますので、長い時間それは有効なC#です。

このルートに行く場合は、発行されたアセンブリを再度アンロードできるようにする必要があります。そのため、AppDomainsの作成とアンロードが必要な場合があります。

私は上記の手法をうまく実装して使用しました。一方、DynamicMethodを使用することができれば、はるかに軽量になります。しかし、私はこのアプローチを試みたことがないので、C#リテラルを使ってDynamicMethodの本体を実装できるかどうかは言えません。

0

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

 
    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; 

    //start with input object and roll out property stack from there. 
    object ret = input; 
    while (props.Count > 0) 
    { 
     var prop = props.Dequeue(); 
     if (string.IsNullOrEmpty(prop)) return null; 

     /*** ADD INDEXER LOGIC HERE ***/ 

     //get the property's value based on the current named item 
     ret = ret.GetType().GetProperty(prop).GetValue(ret, null); 

     if (null.Equals(ret)) return null; 
    } 

    //return looked up value 
    return ret; 
    } 
1

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

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

特に、External RuleSet Toolkit Sampleを参照してください。

1

あなたはいつも私の軽量C#エバールプログラムを試すことができます。これは、C#言語の実質的なサブセットを動的メソッドにコンパイルします。私のウェブサイトの完全な詳細KamimuCode.Com

2

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

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

14

私はオープンソースプロジェクトDynamic Expressoを作成しました。これは、C#構文を使って書かれたテキスト表現を代理人(または表現ツリー)に変換することができます。式は、コンパイルまたはリフレクションを使用せずに解析され、Expression Treesに変換されます。

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に基づいています。

あなたのような何かを書くことができます。

+1

これは面白いです。私はあなたのWebデモでこれを試しましたが、 "Expression expected"というエラーが発生しました:[1,2,3] .Sum() – ShitalShah

+0

@ShitalShah配列宣言はサポートされていません。関数またはパラメータ/変数から作成された配列でSumを呼び出すことができます。 –

関連する問題