3

クラスの型(またはインスタンス)とともに、式ツリーをパラメーターとして受け入れるメソッドに取り組んでいます。

基本的な考え方は、このメソッドが検証に使用されるコレクションに特定のものを追加することです。

public interface ITestInterface
{
    //Specify stuff here.
}

private static void DoSomething<T>(Expression<Func<T, object>> expression, params IMyInterface[] rule)
{
    // Stuff is done here.
}

このメソッドは次のように呼び出されます。

class TestClass
{
    public int MyProperty { get; set; }
}

class OtherTestClass  : ITestInterface
{
    // Blah Blah Blah.
}

static void Main(string[] args)
{
    DoSomething<TestClass>(t => t.MyProperty, 
        new OtherTestClass());
}

渡されるプロパティ名を強く型付けしたいので、このようにしています。

私が苦労しているいくつかのこと..

  1. PropertyInfoDoSomething内で、 (渡された本体から)Tの型を取得し、それをrule[]とともにコレクションに追加したいと思います。現在、expression.Bodyを使用し、「Convert。([propertyname])」から[propertyname]を削除し、リフレクションを使用して必要なものを取得することを考えています。これは面倒で間違っているようです。もっと良い方法はありますか?
  2. これは私が使用している特定のパターンですか?
  3. 最後に、私が行っていることについての私の誤解に関する提案や説明があれば幸いです。また、C#式ツリーに関するリソースや優れた情報も高く評価されます。

ありがとう!

イアン

編集:

expression.Body.ToString()DoSomethingメソッド内で返されるものの例は、上記の例から呼び出された場合に「Convert(t.MyProperty)」を含む文字列です。

強く型付けする必要があるので、プロパティ名を変更してもコンパイルされません。

提案をありがとう!

4

3 に答える 3

3

現在のアプリケーションで実行したいことの多くをコンパイル時、つまり静的型チェックにプッシュするために、式ツリーに大きく依存しています。

式ツリーをトラバースして、「意味のある」何かに変換します。

私が多くのことをやったことの1つは、URLの代わりに、ラムダ関数を宣言するMVCのようなアプローチに依存し、コンパイラーが生成した式ツリーをURLに変換することです。このURLが呼び出されると、私は反対のことをします。このように、私は壊れたリンクのコンパイル時チェックと呼んでいます。これはリファクタリングやオーバーロードでもうまく機能します。このように式ツリーを使うことを考えるのはクールだと思います。

ビジターパターンをチェックしたいと思うかもしれません。最初はあまり意味がないので、始めるのは面倒ですが、すべてを結び付けて、コンパイラー構築の型チェックを解決するための非常に正式な方法です。同じことを行うこともできますが、タイプチェックの代わりに必要なものを出力します。

私が現在頭を悩ませているのは、式の房を翻訳して(または実際には解釈すると言うべきですが)JavaScriptを発行するための単純なフレームワークを構築する機能です。コンパイラによって生成された式ツリーは、オブジェクトモデルとインターフェイスする有効なJavaScriptに変換されるという考え方です。

これについてエキサイティングなのは、問題が発生したときにコンパイラが常に教えてくれる方法であり、最終結果は単なる文字列の集まりですが、重要なのはこれらの文字列がどのように作成されたかです。彼らはいくつかの検証を経て、それは何かを意味します。

それができたら、エクスプレッションツリーではできないことはほとんどありません。

System.Reflection.Emitを使用しているときに、式ツリーを使用して動的コンパイル用の軽量フレームワークを作成しました。これは、コンパイル時に、動的に作成されたアセンブリもコンパイルされるかどうかを基本的に示すことができ、これはリフレクションとシームレスに機能しました。静的型チェック。これはさらに進んでいき、最終的には多くの時間を節約し、非常に機敏で堅牢であることが証明されたものになりました。

だから私はこの種のものが大好きです、そしてこれがメタプログラミングのすべてであり、プログラムを実行するあなたのプログラムでプログラムを書くことです。私はそれを続けて言う!

于 2009-01-07T21:17:02.797 に答える
2

Expression.Body から PropertyInfo オブジェクトを収集することは、別の質問に対する 私の解決策に似ているようです。

于 2008-10-01T01:20:17.030 に答える
2

ここのプロパティであなたがしようとしていることに感謝します。私はこの難問に遭遇しました。書くのはいつも奇妙に感じます:

DoSomething("MyProperty", new OtherClass());

プロパティの名前が変更されたり、呼び出しでテキストが間違って入力されたりすると、問題が発生します。私が学んだことは、これはおそらくテストによって対処しなければならないものだということです。具体的には単体テスト。「DoSomething」呼び出しが正しく機能することを強制する単体テストを作成します。

もう 1 つの方法は、プロパティを属性で装飾し、クラスが構築されたときにその属性を使用してプロパティを検索し、ルールをロードすることです。

[DoSomething(typeof(OtherClass), typeof(OtherClass2))]
public int MyProperty
{
  get;
  set;
}

この場合、コンストラクター (おそらく基本クラスで?) は、OtherClass オブジェクトと OtherClass2 オブジェクトを動的に作成し、それらをプロパティの名前と共にコレクションに読み込みます。

于 2008-10-01T01:28:06.450 に答える