关于泛型函数的C#更具体的版本

Dom*_*ntl 5 c# generics

我有以下功能

public static T Translate<T>(T entity)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

现在如果T是en IEnumerable <>我想要有不同的行为,所以我做了第二个函数

public static IEnumerable<T> Translate<T>(IEnumerable<T> entities)
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

当我像这样调用它

IEnumerable<string> test = new List<string>().AsEnumerable();
Translate(test);
Run Code Online (Sandbox Code Playgroud)

但是当我像这样调用它时

Func<IEnumerable<string>> func = () => new List<string>().AsEnumerable();
Translate(func.Invoke())
Run Code Online (Sandbox Code Playgroud)

它转到了第一个.为什么会发生这种情况,解决这个问题的最佳方法是什么?

UPDATE

我用这个问题构建了一个新的例子

static void Main(string[] args)
{
    Func<IEnumerable<string>> stringFunction = () => new List<string>().AsEnumerable();
    InvokeFunction(ExtendFunction(stringFunction));
}

private static T Convert<T>(T text) where  T : class 
{
    return null;
}

private static IEnumerable<T> Convert<T>(IEnumerable<T> text)
{
    return null;
}

private static Func<T> ExtendFunction<T>(Func<T> func) where T : class 
{
    return () => Convert(func.Invoke());
}

private static T InvokeFunction<T>(Func<T> func)
{
    return func.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

当我希望调用第二个函数时,第一个函数会立即被调用.

Ath*_*ari 7

您需要添加第二个重载ExtendFunction:

private static Func<IEnumerable<T>> ExtendFunction<T> (Func<IEnumerable<T>> func) where T : class
{
    return () => Convert(func.Invoke());
}
Run Code Online (Sandbox Code Playgroud)

或者Convert动态地创建第一个重载调用方法:

private static Func<T> ExtendFunction<T> (Func<T> func) where T : class
{
    return () => Convert((dynamic)func.Invoke());
}
Run Code Online (Sandbox Code Playgroud)

原因是您的方法在编译时ExtendFunction选择Convert方法.您可以避免添加第二个重载ExtendFunction选择所需的Convert方法,或者将Convert方法选择移动到运行时.

  • 是的,它是编译时与运行时问题.OP具有`Func <T>`的`ExtendFunction`,因此编译器不能知道`T`将是`IEnumerable <T>`类型(唯一的约束是`其中T:class`).也可以通过使`ExtendFunction`使用`Func <IEnumerable <T >>`来修复. (5认同)