我有以下功能
public static T Translate<T>(T entity)
{
....
}
现在,如果T是IEnumerable&lt;&gt;我希望有不同的行为,所以我做了第二个功能
public static IEnumerable<T> Translate<T>(IEnumerable<T> entities)
{
....
}
当我像这样调用它时
IEnumerable<string> test = new List<string>().AsEnumerable();
Translate(test);
但是当我像这样调用它时
Func<IEnumerable<string>> func = () => new List<string>().AsEnumerable();
Translate(func.Invoke())
它转到了第一个。 为什么会发生这种情况?解决这个问题的最佳方法是什么?
我用问题构建了一个新例子
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();
}
当我希望调用第二个函数时,第一个函数会立即被调用。
答案 0 :(得分:7)
您需要添加ExtendFunction
的第二次重载:
private static Func<IEnumerable<T>> ExtendFunction<T> (Func<IEnumerable<T>> func) where T : class
{
return () => Convert(func.Invoke());
}
或者让第一个重载动态调用Convert
方法:
private static Func<T> ExtendFunction<T> (Func<T> func) where T : class
{
return () => Convert((dynamic)func.Invoke());
}
原因是您的ExtendFunction
方法在编译时选择Convert
方法。您可以避免添加第二个ExtendFunction
重载,它选择您需要的Convert
方法,或者将Convert
方法选择为运行时。
答案 1 :(得分:0)
在C#中,最接近专业化的是使用更具体的重载;但这只适用于在编译时知道类型的情况。
在您的情况下,由于IEnumerable<T>
而在运行时决定类型,但编译器不能保证它将是IEnumerable<T>
。
如果在main方法中添加此行,则会调用第二个函数。
Convert(text: new List<string>().AsEnumerable());
这是因为在编译时知道类型
所以以这种方式尝试你的Main并查看差异
static void Main(string[] args)
{
Func<IEnumerable<string>> stringFunction = () => new List<string>().AsEnumerable();
InvokeFunction(ExtendFunction(stringFunction));//first function invoked
Convert(text: new List<string>().AsEnumerable());//second function invoked
}
答案 2 :(得分:-1)
我们通过实际给该方法另一个名称解决了我们的问题。在您的情况下,这将是第二个名为:
的方法public static IEnumerable<T> TranslateAll<T>(IEnumerable<T> entities)