我想要一个扩展方法来打印IEnumerable的所有内容< X>
public static IEnumerable<T> log_elements<T>(this IEnumerable<T> collection, bool recursive = true)
{
Form1.log("[");
foreach (T i in collection)
if(recursive&&(i.GetType().GetGenericTypeDefinition()==typeof(IEnumerable<>)))
(IEnumerable<>)i.log_elements();//This doesn't work
else
Form1.log(i);
Form1.log("]");
return collection;
}
如果它包含IEnumerable&lt; Y&gt;,也应该调用该方法。
我无法添加log_elements<T>(this IEnumerable<IEnumerable<T>>,bool)
,因为IEnumerable<T>
与原始方法的T
匹配。
我几乎可以肯定,在c#中应该有这样一个简单问题的解决方案。
答案 0 :(得分:2)
从IEnumerable
更改为非通用public static IEnumerable<T> log_elements<T>(this IEnumerable<T> collection, bool recursive = true)
{
logElementsInternal(collection, recursive);
return collection;
}
private static void logElementsInternal(IEnumerable collection, bool recursive)
{
Form1.log("[");
foreach (var i in collection)
if(recursive && i is IEnumerable)
logElementsInternal((IEnumerable)i);
else
Form1.log(i);
Form1.log("]");
}
(通用版本无论如何继承)。
(clientKampanj.VisaKampanj(vara.ProduktNamn) / 100)
答案 1 :(得分:1)
编辑备注:
这不涉及IEnumerable,但忽略了反射的需要。
这段代码的主要目标是“简单易行”。理解语法并尽可能重用。
如果您确实希望递归,则以下代码应满足您的目的;它更可重用,因为它不依赖于方法范围之外的变量:
/// <summary>
/// Returns the top level items including all their recursive descendants.
/// </summary>
/// <typeparam name="T">The generic enumerable type parameter.</typeparam>
/// <param name="source">The source to traverse.</param>
/// <param name="childPropertyExpression">The recursive property expression.</param>
/// <returns>IEnumerable(<typeparamref name="T"/>)</returns>
public static IEnumerable<T> IncludeDescendants<T>(this IEnumerable<T> source, Expression<Func<T, IEnumerable<T>>> childPropertyExpression)
{
// The actual recursion is processed inside the private static method
// This method is serving the purpose of writing expressions.
var items = IncludeDescendants(source, childPropertyExpression.Compile());
foreach (var item in items)
{
yield return item;
}
}
private static IEnumerable<T> IncludeDescendants<T>(IEnumerable<T> source, Func<T, IEnumerable<T>> childPropertyFunc)
{
foreach (var item in source)
{
yield return item;
var subSource = childPropertyFunc.Invoke(item);
if (subSource != null)
{
foreach (var subItem in IncludeDescendants(subSource, childPropertyFunc))
{
yield return subItem;
}
}
}
}
用法:
var allChildrenRecursive = MyObject.Children.IncludeDescendants(c => c.Children);
foreach(var child in allChildrenRecursive)
{
Log(child);
}
在这种情况下,每个孩子都有一个相同类型孩子的递归集合 请注意循环引用,因为在这种情况下,这将达到您的堆栈允许的范围。 (StackOverflowException)。强>
答案 2 :(得分:-1)
var a = i as IEnumerable<T>;
(IEnumerable<T>) a.log_elements(true);