22

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

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

アディバルダ

4

9 に答える 9

20

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

var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
于 2009-06-21T16:57:57.833 に答える
19

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

次のように書くことができます:

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);

私の仕事は、ScottGuの記事http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspxに基づいています。

于 2013-02-03T09:35:58.040 に答える
8

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

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

于 2009-06-21T14:53:55.957 に答える
1

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

これは他のいくつかの提案よりもはるかに手間がかかりますが、一方で、C#パーサーに手間のかかる作業を任せるので、有効なC#である限り、C#パーサーに投げたすべてを処理できるはずです。 。

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

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

于 2009-06-21T15:04:01.270 に答える
1

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

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

特に、外部RuleSetToolkitサンプルを参照してください。

于 2009-06-21T15:25:32.570 に答える
1

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

于 2010-06-09T04:26:40.567 に答える
1

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

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

于 2011-06-10T02:35:43.627 に答える
0

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

  public static object FindDottedProperty(this object input、string propertyName)
  {{
    if(input == null)
      nullを返します。

    if(string.IsNullOrEmpty(propertyName))
      nullを返します。

    キューの小道具=newQueue(propertyName.Split('。'));
    if(props.Count == 0)はnullを返します。

    //入力オブジェクトから開始し、そこからプロパティスタックを展開します。
    オブジェクトret=入力;
    while(props.Count> 0)
    {{
      var prop = props.Dequeue();
      if(string.IsNullOrEmpty(prop))return null;

      /***ここにインデクサロジックを追加***/

      //現在の名前付きアイテムに基づいてプロパティの値を取得します
      ret = ret.GetType()。GetProperty(prop).GetValue(ret、null);

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

    //検索した値を返します
    retを返します。
  }
于 2009-06-21T15:11:06.857 に答える
0

AFAIKには、そのような組み込みのEval関数はありません。Regex+Reflectionの方法を使用する必要があります。VisualStudioも同じことをしていると思います。

于 2009-06-21T14:48:49.663 に答える