我有一个难以理解的难题,我很确定这只是我误解了一些东西。
我有以下扩展方法:
public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
{
foreach (var number in enumeration)
{
action?.Invoke(number);
}
}
该扩展方法允许我执行以下操作:
var curiousNumbers = new List<BigInteger>();
// some code to fill curiousNumbers
curiousNumbers.ForEach(x => DebugLog(x));
protected static void DebugLog(object logmessage)
{
Logger.Log(logmessage.ToString());
}
但是,当我尝试使用此语法时:
curiousNumbers.ForEach(DebugLog);
我收到以下的编译错误: “BaseProblem.DebugLog(object)”的重载不匹配委托“Action&lt;&gt; BigInteger&lt;&gt;”
现在如果我引入一个带有显式BigInteger类型的新DebugLog方法,那么所有内容都会编译并运行:
protected static void DebugLog(BigInteger logmessage)
{
Logger.Log(logmessage.ToString());
}
这有效但如果我有一个Ints列表怎么办?我必须为每个显式类型添加另一个DebugLog方法。有没有办法可以重写ForEach扩展方法或DebugLog方法,它们都处理所有类型并允许curiousNumbers.ForEach(DebugLog)语法?
答案 0 :(得分:3)
您获得的编译错误是由于方法DebugLog
的参数类型为object
,但您传递的序列包含BigInteger
类型的元素。 T
的泛型ForEach<T>
应该评估哪种类型?它不可能同时存在。使DebugLog
方法也通用,以解决您的问题:
protetected static void DebugLog<T>(T message)
{
Logger.Log(message.ToString());
}
答案 1 :(得分:2)
看看原型:
public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action)
T
适用于动作和输入可枚举,以及您有额外约束的原因。
由于您正在迭代T对象,因此您可能希望运行T动作。
您可以选择:
1.创建一个T1,T2 ForEach:
public static void ForEach<T1,T2>(this IEnumerable<T1> enumeration, Action<T2> action)
2.创建DebugLog
的通用实现,而不是将对象作为参数传递。