在Func中使用泛型类型参数,并使用特定类型调用Func?

时间:2018-07-16 15:21:59

标签: c# generics

我有以下方法,其中在T中使用Func

public void DoSomething<T>(string someString, Func<T, bool> someMethod) 
{    
    if(someCondition) 
    {
        string A;
        bool resultA = someMethod(A);
    }
    else 
    {
        string[] B;
        bool resultB = someMethod(B);
    }    
    // Some other stuff here ...
}

我通过以下方式调用DoSomething方法:

DoSomething<string>("abc", someMethod);
DoSomething<string[]>("abc", someMethod);

并且someMethod存在以下定义:

bool someMethod(string simpleString);
bool someMethod(string[] stringArray);

现在,编译失败,方法DoSomething中出现以下错误:

cannot convert from 'string' to 'T'
cannot convert from 'string[]' to 'T'

我无法确定是否有解决问题的方法,或者我正在尝试的方法不可行。它看上去与问题How can I pass in a func with a generic type parameter?类似,尽管它对我的情况没有帮助。

2 个答案:

答案 0 :(得分:5)

您的示例似乎有点不一致,但是如果您一般地编写东西,它应该看起来像这样:

public void DoSomething<T>(string someString, Func<T, bool> someMethod) 
{
    T a;
    someMethod(a);
}

请注意,与其使用if在类型之间进行选择,然后将类型声明为stringstring[],我们只是将类型声明为T,在编译代码时将替换该代码,以使其适合该功能。

当您发现自己使用ifswitch case在类型之间进行选择时,可能就不需要通用的解决方案了;实际上,逻辑根本不是通用的。这是具体的。在这种情况下,只需编写两个原型:

public void DoSomething(string someString, Func<string, bool> someMethod) 
{    
    string A;
    bool resultA = someMethod(A);
}


public void DoSomething(string someString, Func<string[], bool> someMethod) 
{    
    string[] A;
    bool resultA = someMethod(A);
}

这被称为method overloading。通过从提供的函数中推断类型,编译器将自动选择具有正确参数的正确方法。

答案 1 :(得分:0)

您可以通过反射来实现:

public void DoSomething<T>(string someString, Func<T, bool> someMethod)
{
    var args = new Dictionary<Type, object>
    {
        [typeof(string)] = "string", //string A;
        [typeof(string[])] = new[] { "string" }, //string[] B;
    };
    var arg = args[typeof(T)];
    var result = (bool)someMethod.Method.Invoke(someMethod.Target, new[] { arg });
}

用法:

DoSomething<string>("abc", someMethod);
DoSomething<string[]>("abc", someMethod);