質問
この質問にはすでに回答があります:
たとえば、 myobject.firstMember.secondMember [3] .text
のように、正確なメンバーパスのテキストステートメントがある間、実行時にオブジェクトの値を評価する必要があります。
正規表現を使用してこのテキストステートメントを解析し、リフレクションを使用してテキスト値を評価することを考えましたが、それを行う前にC#が何らかの eval 機能をサポートしているかどうか疑問に思いますか?そのため、自分で解析を行う必要はありません。マイクロソフトは、イミディエイトウィンドウまたはウォッチウィンドウでこれをどのように行いますか?
どうもありがとう、
アディ・バルダ
解決
おそらく最も簡単な方法は、 DataBinderを使用することです。 System.Web.UIの.Eval :
var foo = new Foo() { Bar = new Bar() { Value = "Value" } };
var value = DataBinder.Eval(foo, "Bar.Value");
他のヒント
オープンソースプロジェクト Dynamic Expresso を作成しました。これは、デリゲート(または式ツリー)へのC#構文。式は解析され、コンパイルまたはリフレクションを使用せずに式ツリーに変換されます。
次のように書くことができます:
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);
私の仕事はScott Guの記事 http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic- query-library.aspx 。
将来(5.0の期間)に、「サービスとしてのコンパイラ」これができるかもしれません。実際には、「モノ」でこれの多くを行うことができるかもしれません。 ( CsharpRepl および Mono.CSharp -ただし、ローカルを使用できるようにするには、コンテキストについてもっと知る必要があると思います 評価
の変数などa>)-ただし、現在のMS .NETサービスにはこれに対するサポートはありません。
今のところ、多くのデータバインディングコードが行うようなことをする必要があります...「。」などのトークンで分割反射を使用します。厳密に言えば、バインディングコードは実際には直接反映ではなく TypeDescriptor
/ PropertyDescriptor
を使用しますが、効果は同じです。
やや重いアプローチですが、C#CodeDomを使用して、そのコード行だけのメソッドを含む新しいアセンブリを発行できます。
これは、他のいくつかの提案よりもはるかに手間がかかりますが、一方で、C#パーサーに重い負荷をかけさせるので、投げるすべてを処理できるはずです。有効なC#です。
そのルートに進む場合は、発行されたアセンブリを再度アンロードできることも確認する必要があります。そのため、AppDomainの作成とアンロードが必要になる場合があります。
上記の手法を正常に実装および使用しました。一方、 DynamicMethod はるかに軽量になります。ただし、私はそのアプローチを試したことがないため、C#リテラルを使用してDynamicMethodの本体を実装できるかどうかは言えません。
実際、Windows Workflow Foundationの式評価およびルールエンジン機能は、このようなことを実行できます。 Windows Workflow Foundation Rules Engineの紹介を参照してください。
これらのコンポーネントの興味深い点の1つは、独自のアプリケーションで設計時コンポーネントをホストして、独自のカスタムクラスのコンテキストで動作する一連のルールや式を設計できるように設計されていることです。たとえば、「myObject」に対する式を設計するように指示すると、テキストプロパティを持つ型を生成するインデクサーを持つsecondMemberを持つfirstMemberがあることがわかります。式およびルールをXMLとして永続化し、実行時にデザイナーを使用する必要なく、実行時にそれらを読み取ることができます。
特に、外部RuleSet Toolkitサンプルを参照してください。
残念ながら、C#には、あなたが求めていることを正確に行うためのネイティブ機能がありません。
ただし、私のC#evalプログラムでは、C#コードを評価できます。実行時にC#コードを評価し、" myobject.firstMember.secondMember [3] .text "などの式を含む多くのC#ステートメントをサポートします。実際、このコードは任意の.NETプロジェクト内で使用できますが、C#構文の使用に制限されています。詳細については、私のウェブサイト http://csharp-eval.com をご覧ください。
あなたはいつでも私の軽量C#Evalプログラムを試すことができます。 C#言語の実質的なサブセットを動的メソッドにコンパイルします。 GitHubリポジトリの詳細 DavidWynne / CSharpEval
AFAIKには、このような組み込みの評価関数はありません。 Regex + Reflectionを使用する必要があります。 Visual Studioも同じことをしていると思います。
動的にネストされたプロパティを見つけるために使用しているものと似たものがあります。インデクサーのロジックを追加する必要があります...そしていくつかの追加のチェック...呼び出しメソッドで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; //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; }