首页 文章

C#方法没有重载匹配委托Action ForEach

提问于
浏览
0

我有一个难以理解的难题,我很确定这只是我误解了一些东西 .

我有以下扩展方法:

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 <> BigInteger <>'

现在,如果我引入一个带有显式BigInteger类型的新DebugLog方法,则所有内容都会编译并运行:

protected static void DebugLog(BigInteger logmessage)
{
    Logger.Log(logmessage.ToString());
}

这有效,但如果我有一个Ints列表怎么办?我必须为每个显式类型添加另一个DebugLog方法 . 有没有办法可以重写ForEach扩展方法或DebugLog方法,它们都处理所有类型并允许curiousNumbers.ForEach(DebugLog)语法?

2 回答

  • 3

    您获得的编译错误是由于方法 DebugLog 具有 object 类型的参数,但您传递的序列包含 BigInteger 类型的元素 . ForEach<T> 的泛型类型 T 应该评估哪种类型?它不可能同时存在 . 使 DebugLog 方法也是通用的,以解决您的问题:

    protetected static void DebugLog<T>(T message)
    {
        Logger.Log(message.ToString());
    }
    
  • 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 的通用实现,而不是将对象作为参数传递 .

相关问题