将泛型函数作为参数传递

Max*_*Max 12 c# generics

我知道我正在做的事情可以用不同的方式完成,但我对事情的运作方式很好奇.以下是一个不编译的简化代码,但它应该显示我的目标.

private void Execute()
{
    GeneralizedFunction("1", "2", i => Transform(i));
}

void GeneralizedFunction(string aStringA, string aStringB, Func<string, T> aAction)
{
    A result1 = aAction(aStringA);
    B result2 = aAction(aStringB);
    // Do something with A and B here
}

T Transform<T>(string aString)
{
    return default(T);
}
Run Code Online (Sandbox Code Playgroud)

Transform是从字符串到某个对象的通用转换(想想反序列化). GeneralizedFunction使用两个转换特化:一个用于类型A,一个用于类型B.我知道我可以通过许多其他方式执行此操作(例如通过引入对象类型的参数),但我正在寻找解释是否有可能或不可能使用泛型/ lambdas.如果Transform在作为参数传递给GeneralizedFunction之前是专用的,那么它是不可能的.那么问题是为什么这种可能性受到限制.

sin*_*law 7

这个答案并没有解释为什么,只是如何解决这个限制.

您可以传递具有此类函数的对象,而不是传递实际函数:

interface IGenericFunc
{
    TResult Call<TArg,TResult>(TArg arg);
}

// ... in some class:

void Test(IGenericFunc genericFunc)
{
    // for example's sake only:
    int x = genericFunc.Call<String, int>("string");
    object y = genericFunc.Call<double, object>(2.3);
}
Run Code Online (Sandbox Code Playgroud)

对于您的特定用例,可以简化为:

interface IDeserializerFunc
{
    T Call<T>(string arg);
}

// ... in some class:
void Test(IDeserializerFunc deserializer)
{
    int x = deserializer.Call<int>("3");
    double y = deserializer.Call<double>("3.2");
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ias 1

尝试以下签名:

void GeneralizedFunction<T>(string aStringA, string aStringB, Func<string, T> aAction)
Run Code Online (Sandbox Code Playgroud)

(请注意,GeneralizedFunction 必须是泛型的;编译器在调用方法时会自动猜测类型参数)。