C# 任意嵌套的 IEnumerable 对象
C# Arbitrarily Nested IEnumerable object
我正在尝试编写一些方法来处理 C# 中的多层 IEnumerable 对象。以下示例是名为“ConsoleWrite”的方法,用于将 IEnumerable 对象中的每个字符串打印到控制台。
public void ConsoleWrite(IEnumerable<string> StringData)
{
foreach (var EachString in StringData)
{
Console.Write(EachString);
}
}
“ConsoleWrite”方法的用法。
List<string> Test1 = new List<string>();
Test1.Add("123");
Test1.Add("456");
ConsoleWrite(Test1);
运行良好,输出为“123456”。但是,当涉及到 List<List<string>>
的情况时,这个 ConsoleWrite 方法需要如下重载。
public void ConsoleWrite(IEnumerable<IEnumerable<string>> StringData)
{
foreach (var EachString in StringData)
{
ConsoleWrite(EachString);
}
}
测试案例List<List<string>>
.
List<List<string>> Test2 = new List<List<string>>();
Test2.Add(Test1);
Test2.Add(Test1);
ConsoleWrite(Test2)
另外,对于List<List<List<string>>>
的情况,这个ConsoleWrite方法需要重载为public void ConsoleWrite(IEnumerable<IEnumerable<IEnumerable<string>>> StringData)
。我想知道是否有任何方法可以轻松处理任意嵌套的列表 IEnumerable<...<IEnumerable<string>>>
而无需逐一重载?
欢迎提出任何建议。
你可以只使用非泛型 IEnumerable
、一些 模式匹配 和 递归
public static void ConsoleWrite(IEnumerable source)
{
foreach (var item in source)
if (item is string str)
Console.WriteLine(str);
else if (item is IEnumerable enumerable)
ConsoleWrite(enumerable);
}
例子
var list = new List<string> {"1", "2", "3"};
ConsoleWrite(list);
var list2 = new List<List<string>>
{
new List<string>(){"4", "5", "6"},
new List<string>(){"7", "8", "9"}
};
ConsoleWrite(list2);
输出
1
2
3
4
5
6
7
8
9
另一种更通用的方法是创建一个扩展方法,就像SelectMany
和递归
public static class Extensions
{
public static IEnumerable<T> FlattenMany<T>(this IEnumerable source)
{
foreach (var item in source)
if (item is T t)
yield return t;
else if (item is IEnumerable enumerable)
foreach (var elem in enumerable.FlattenMany<T>())
yield return elem;
}
}
用法
var list2 = new List<List<string>>
{
new List<string>() {"4", "5", "6"},
new List<string>() {"7", "8", "9"}
};
var results = list2.FlattenMany<string>();
我正在尝试编写一些方法来处理 C# 中的多层 IEnumerable 对象。以下示例是名为“ConsoleWrite”的方法,用于将 IEnumerable 对象中的每个字符串打印到控制台。
public void ConsoleWrite(IEnumerable<string> StringData)
{
foreach (var EachString in StringData)
{
Console.Write(EachString);
}
}
“ConsoleWrite”方法的用法。
List<string> Test1 = new List<string>();
Test1.Add("123");
Test1.Add("456");
ConsoleWrite(Test1);
运行良好,输出为“123456”。但是,当涉及到 List<List<string>>
的情况时,这个 ConsoleWrite 方法需要如下重载。
public void ConsoleWrite(IEnumerable<IEnumerable<string>> StringData)
{
foreach (var EachString in StringData)
{
ConsoleWrite(EachString);
}
}
测试案例List<List<string>>
.
List<List<string>> Test2 = new List<List<string>>();
Test2.Add(Test1);
Test2.Add(Test1);
ConsoleWrite(Test2)
另外,对于List<List<List<string>>>
的情况,这个ConsoleWrite方法需要重载为public void ConsoleWrite(IEnumerable<IEnumerable<IEnumerable<string>>> StringData)
。我想知道是否有任何方法可以轻松处理任意嵌套的列表 IEnumerable<...<IEnumerable<string>>>
而无需逐一重载?
欢迎提出任何建议。
你可以只使用非泛型 IEnumerable
、一些 模式匹配 和 递归
public static void ConsoleWrite(IEnumerable source)
{
foreach (var item in source)
if (item is string str)
Console.WriteLine(str);
else if (item is IEnumerable enumerable)
ConsoleWrite(enumerable);
}
例子
var list = new List<string> {"1", "2", "3"};
ConsoleWrite(list);
var list2 = new List<List<string>>
{
new List<string>(){"4", "5", "6"},
new List<string>(){"7", "8", "9"}
};
ConsoleWrite(list2);
输出
1
2
3
4
5
6
7
8
9
另一种更通用的方法是创建一个扩展方法,就像SelectMany
和递归
public static class Extensions
{
public static IEnumerable<T> FlattenMany<T>(this IEnumerable source)
{
foreach (var item in source)
if (item is T t)
yield return t;
else if (item is IEnumerable enumerable)
foreach (var elem in enumerable.FlattenMany<T>())
yield return elem;
}
}
用法
var list2 = new List<List<string>>
{
new List<string>() {"4", "5", "6"},
new List<string>() {"7", "8", "9"}
};
var results = list2.FlattenMany<string>();