8

Func<>型引数を動的に設定する方法はありますか?無限のifステートメントを使用する必要はありませんか?

何かのようなもの:

Type t = Type.GetType("System.Decimal");
Func<t> foo = new Func<t>(some_function);

それ以外の:

Func<Decimal> foo = new Func<Decimal>(some_function);

アップデート:

ここに私のコードからのスニペットがあります:

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType;
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka");
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression);
Expression final = Expression.Convert(expr, t);
if (t == typeof(decimal))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
if (t == typeof(decimal?))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal?>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
else if (t == typeof(int))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, int>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
else if (t == typeof(int?))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, int?>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
else if (t == typeof(string))
{
    var lambda = Expression.Lambda<Func<string>>(final, null);
    o = lambda.Compile().Invoke();
}

pd.Polje は文字列 - 「StavkaDokumenta」クラス内のプロパティの名前です。pd.Expression は、Polje の型に評価される必要がある文字列式です。stavka は StavkaDokumenta のインスタンスです。

4

1 に答える 1

9

本当に必要なものを示したので、答えははるかに簡単です。明らかにその式の戻り値にのみ関心があるので、コードを次のように変更できます。

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType;
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka");
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression);
Expression final = Expression.Convert(expr, t);

if (t == typeof(string))
{
    var lambda = Expression.Lambda<Func<string>>(final, null);
    o = lambda.Compile().Invoke();
}
else
{
    var lambda = Expression.Lambda(final, pe);
    o = lambda.Compile().DynamicInvoke(stavka);
}

古い答え:

Func<T>これを実現するには、ジェネリックスと暗黙の変換を使用できます。

Func<T> GetFunc<T>(Func<T> func)
{
    return func;
}

次のようなメソッドグループで呼び出します。

var foo = GetFunc(SomeMethod);

これは、次のようになっていることを前提としていSomeMethodます。

decimal SomeMethod()
{
    // ...
}

fooタイプになりFunc<decimal>ます。の戻りタイプが、の場合、SomeMethodstringタイプは。にfooなりますFunc<string>


このコードで何が起こるかは次のとおりです。

渡されるパラメータGetFuncは、いわゆる「メソッドグループ」であり、タイプの変数ではありませんFunc<T>。ただし、メソッドグループから次の変数への暗黙の変換が存在しますFunc<T>

Func<decimal> func = SomeMethod; // an implicit conversion happens here

その暗黙の変換は、まさにここで起こっていることです。GetFunc呼び出される前に、メソッドグループSomeMethodはタイプの変数に変換されますFunc<T>。に使用される具象型Tは、メソッドの戻り型に基づいてコンパイラによってさらに推測されSomeMethod()ます。
私たちの目標はFunc<T>、メソッドグループに基づいてのインスタンスを作成することでした。また、メソッドが呼び出される前にパラメーターの変換で既に発生しているため、作成されたインスタンスをメソッドから返すだけです。

于 2012-04-16T14:47:13.947 に答える