c# - 如何递归地将 IEnumerable<T> 转换为字符串?

标签 c# generics

我想要一个可以调用的函数来替代 .ToString(),它将显示集合的内容。

我已经试过了:

public static string dump(Object o) {
    if (o == null) return "null";
    return o.ToString();
}

public static string dump<K, V>(KeyValuePair<K, V> kv) {
    return dump(kv.Key) + "=>" + dump(kv.Value);
}

public static string dump<T>(IEnumerable<T> list) {
    StringBuilder result = new StringBuilder("{");
    foreach(T t in list) {
        result.Append(dump(t));
        result.Append(", ");
    }
    result.Append("}");
    return result.ToString();
}

但是第二个重载永远不会被调用。例如:

List<string> list = new List<string>();
list.Add("polo");
Dictionary<int, List<string>> dict;
dict.Add(1, list);
Console.WriteLine(dump(dict));

我期待这样的输出:

{1=>{"polo", }, }

实际发生的是这样的: dict 被正确解释为 IEnumerable<KeyValuePair<int, List<string>>> , 所以第三个重载被调用。

第三个重载在 KeyValuePair 上调用 dump>。这应该(?)调用第二个重载,但它没有——它调用了第一个重载。

所以我们得到这个输出:

{[1=>System.Collections.Generic.List`1[System.String]], }

它是从 KeyValuePair 的 .ToString() 方法构建的。

为什么不调用第二个重载?在我看来,运行时应该拥有识别具有完整通用参数的 KeyValuePair 并调用它所需的所有信息。

最佳答案

泛型是编译时的概念,不是运行时的。 换句话说,类型参数在编译时解析。

在您的 foreach 中调用 dump(t) 并且 t 的类型为 T。 但目前除了知道它是一个 Object 之外,对 T 一无所知。 这就是调用第一个重载的原因。

关于c# - 如何递归地将 IEnumerable<T> 转换为字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15858515/

相关文章:

c# - 我想存储特定于 "Arabian Standard Time"的日期,而不考虑 Web 服务器上的时区

c# - 在 C# 中使用堆栈和队列的括号检查器

c# - 使用 MVC $.ajax() 一致地从 Controller 中的操作获取数据?

c# - 使用 sandcaSTLe 将示例代码放入文档中

Func + 扩展方法 + lambda 中的 C# 歧义

generics - Rust 中的通用占位符或默认值

c# - 为什么这个 Actor 是不可能的?

C# UWP XAML 动画

swift - 在泛型类中传递泛型参数

java - 在 Java 中查找实际类型参数