4

式ツリーを使用して、実行時にデリゲートを構築します。

Type type = GetType();
ParameterExpression parameterType = Expression.Parameter(type);
...
Delegate delegate = Expression.Lambda(*something*, parameterType).Compile();

メソッド GetType() によって返される型がコンパイル時にわかりません。高価な DynamicInvoke() メソッドを使用せずにデリゲートを呼び出すことは可能ですか?

編集 :

私のアプリケーションには、基本抽象クラスがあります。

public abstract class Frame
{
    public string RawContent { get; set; }

    // ...
}

実行時に、アプリケーションは Frame を継承するいくつかのオブジェクトを使用します。これらのオブジェクトは MEF (プラグイン) と共に読み込まれるため、コンパイル時にはこれらのオブジェクトの型はわかりません。アプリケーションの目的は、エラーのあるデータを含むオブジェクトをフィルタリングすることです。たとえば、プログラムが次のようなクラスのオブジェクトを処理する必要がある場合:

public class Frame01 : Frame
{
    public int Counter6hours { get; set; }

    public int DeltaCounter6hours { get; set; }
}

ユーザーがアプリケーションの構成ファイルに次のように記述できるようにしたいと思います。

<filtersSection>
    <filters>
            <filter class="Frame01" expression="Counter6hours < 0" />
            <filter class="Frame01" expression="DeltaCounter6hours > 2500" />
    </filters>
<filtersSection>

なんとか式ツリーを作成し、それを各フィルターのデリゲートにコンパイルしました。しかし、コンパイル時に Frame01 の型がわからないため、それを Func にキャストすることはできません。基礎となるメソッド。アプリケーションは大量のオブジェクトを処理する必要があり、パフォーマンスの問題が心配です... したがって、この例では、プログラムで Func オブジェクトを構築しようとしていますが、それが可能かどうかはわかりません。

PS : 下手な英語ですみません...

4

2 に答える 2

4

これがあなたの望むものであるかどうかはまだ完全にはわかりませんが、必要なのはキャストだけだと思います。式には型のパラメーターがありFrame、それをキャストしてFrame01、その上でフィルターを実行します。

コード内:

var type = typeof(Frame01);

var param = Expression.Parameter(typeof(Frame));
var casted = Expression.Convert(param, type);

// this part will be dynamic in your actual code
var condition = Expression.LessThan(
    Expression.Property(casted, "Counter6hours"), Expression.Constant(0));

var result = Expression.Lambda<Func<Frame, bool>>(condition, param)
    .Compile();

これで、次のテストに合格します。

Assert.IsTrue(result(new Frame01 { Counter6hours = -1 }));
Assert.IsFalse(result(new Frame01 { Counter6hours = 1 }));
Assert.Throws<InvalidCastException>(() => result(new Frame02()));
于 2012-12-13T13:00:03.150 に答える
0

あなたのコメントから、あなたは最終的にFunc<object, bool>

したがって、型のパラメーターを使用して式ツリーを構築する必要がありますobject

このようなものが動作します:

var p = Expression.Parameter(typeof(object));
var c = Expression.Constant(true);
var lambda = Expression.Lambda(c,p);
var fn = ( Func<object, bool> ) lambda.Compile();

それで:

bool b = fn( ...some object... );
于 2012-12-11T15:47:46.520 に答える