Procházet zdrojové kódy

降低代码行数,优化重复代码

luche lin před 1 rokem
rodič
revize
ccc48f6c7d
1 změnil soubory, kde provedl 117 přidání a 270 odebrání
  1. 117 270
      Masuit.Tools.Abstractions/Models/TreeExtensions.cs

+ 117 - 270
Masuit.Tools.Abstractions/Models/TreeExtensions.cs

@@ -20,10 +20,8 @@ public static class TreeExtensions
     /// <param name="items"></param>
     /// <param name="func"></param>
     /// <returns></returns>
-    public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, Func<T, bool> func) where T : class, ITreeChildren<T>
-    {
-        return Flatten(items).Where(func);
-    }
+    public static IEnumerable<T> Filter<T>(this IEnumerable<T> items, Func<T, bool> func) where T : class, ITreeChildren<T> 
+        => Flatten(items).Where(func);
 
     /// <summary>
     /// 过滤
@@ -32,10 +30,8 @@ public static class TreeExtensions
     /// <param name="items"></param>
     /// <param name="func"></param>
     /// <returns></returns>
-    public static IEnumerable<Tree<T>> Filter<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, bool> func) where T : class
-    {
-        return Flatten(items).Where(func);
-    }
+    public static IEnumerable<Tree<T>> Filter<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, bool> func) where T : class 
+        => Flatten(items).Where(func);
 
     /// <summary>
     /// 过滤
@@ -44,10 +40,8 @@ public static class TreeExtensions
     /// <param name="item"></param>
     /// <param name="func"></param>
     /// <returns></returns>
-    public static IEnumerable<T> Filter<T>(this T item, Func<T, bool> func) where T : class, ITreeChildren<T>
-    {
-        return Flatten(item).Where(func);
-    }
+    public static IEnumerable<T> Filter<T>(this T item, Func<T, bool> func) where T : class, ITreeChildren<T> 
+        => Flatten(item).Where(func);
 
     /// <summary>
     /// 过滤
@@ -56,10 +50,8 @@ public static class TreeExtensions
     /// <param name="item"></param>
     /// <param name="func"></param>
     /// <returns></returns>
-    public static IEnumerable<Tree<T>> Filter<T>(this Tree<T> item, Func<Tree<T>, bool> func) where T : class
-    {
-        return Flatten(item).Where(func);
-    }
+    public static IEnumerable<Tree<T>> Filter<T>(this Tree<T> item, Func<Tree<T>, bool> func) where T : class 
+        => Flatten(item).Where(func);
 
     /// <summary>
     /// 平铺开
@@ -68,37 +60,9 @@ public static class TreeExtensions
     /// <param name="items"></param>
     /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
     /// <returns></returns>
-    public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Action<T, T> optionAction = null) where T : class, ITreeChildren<T>
-    {
-        if (items == null)
-        {
-            yield break;
-        }
-
-        // 使用一个栈来存储待处理的节点
-        var stack = new Stack<T>();
-        // 首先将所有项压入栈中
-        foreach (var item in items)
-        {
-            stack.Push(item);
-        }
-
-        // 循环直到栈为空
-        while (stack.Count > 0)
-        {
-            // 弹出栈顶的节点
-            var currentItem = stack.Pop();
-            yield return currentItem;
-
-            // 为当前节点设置子节点,如果optionAction不为空,则对每个子节点执行操作
-            var children = currentItem.Children ?? new List<T>();
-            foreach (var child in children)
-            {
-                optionAction?.Invoke(child, currentItem);
-                stack.Push(child); // 将子节点压入栈中
-            }
-        }
-    }
+    public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Action<T, T> optionAction = null)
+        where T : class, ITreeChildren<T>
+        => items.Flatten(i => i.Children ?? [], optionAction);
 
     /// <summary>
     /// 平铺开
@@ -108,37 +72,28 @@ public static class TreeExtensions
     /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
     /// <returns></returns>
     public static IEnumerable<T> Flatten<T>(this T p, Action<T, T> optionAction = null) where T : class, ITreeChildren<T>
-    {
-        if (p == null)
-        {
-            return [];
-        }
-
-        return Flatten([p], t => t.Children, optionAction);
-    }
+        => p != null
+            ? Flatten([p], t => t.Children, optionAction)
+            : [];
 
     /// <summary>
     /// 平铺开任意树形结构数据
     /// </summary>
     /// <typeparam name="T"></typeparam>
     /// <param name="items"></param>
-    /// <param name="selector"></param>
+    /// <param name="selector">子节点获取方法</param>
     /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
     /// <returns></returns>
     public static IEnumerable<T> Flatten<T>(this IEnumerable<T> items, Func<T, IEnumerable<T>> selector, Action<T, T> optionAction = null)
     {
         if (items == null)
-        {
             yield break;
-        }
 
         // 使用一个队列来存储待处理的节点
         var queue = new Queue<T>();
         // 首先将所有项加入队列
         foreach (var item in items)
-        {
             queue.Enqueue(item);
-        }
 
         // 循环直到队列为空
         while (queue.Count > 0)
@@ -150,7 +105,7 @@ public static class TreeExtensions
             yield return currentItem;
 
             // 获取当前节点的所有子节点
-            var children = selector(currentItem) ?? new List<T>();
+            var children = selector(currentItem) ?? [];
 
             // 将所有子节点加入队列
             foreach (var child in children)
@@ -169,15 +124,11 @@ public static class TreeExtensions
     /// <param name="items"></param>
     /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
     /// <returns></returns>
-    public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Action<Tree<T>, Tree<T>> optionAction = null) where T : class
-    {
-        if (items == null)
-        {
-            return [];
-        }
-
-        return Flatten(items, t => t.Children, optionAction);
-    }
+    public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items,
+        Action<Tree<T>, Tree<T>> optionAction = null) where T : class
+        => items != null
+            ? Flatten(items, t => t.Children, optionAction)
+            : [];
 
     /// <summary>
     /// 平铺开
@@ -196,51 +147,6 @@ public static class TreeExtensions
         return Flatten([p], t => t.Children, optionAction);
     }
 
-    /// <summary>
-    /// 平铺开任意树形结构数据
-    /// </summary>
-    /// <typeparam name="T"></typeparam>
-    /// <param name="items"></param>
-    /// <param name="selector"></param>
-    /// <param name="optionAction">平铺时子级需要做的操作,参数1:子级对象,参数2:父级对象</param>
-    /// <returns></returns>
-    public static IEnumerable<Tree<T>> Flatten<T>(this IEnumerable<Tree<T>> items, Func<Tree<T>, IEnumerable<Tree<T>>> selector, Action<Tree<T>, Tree<T>> optionAction = null)
-    {
-        if (items == null)
-        {
-            yield break;
-        }
-
-        // 使用一个队列来存储待处理的节点
-        var queue = new Queue<Tree<T>>();
-        // 首先将所有项加入队列
-        foreach (var item in items)
-        {
-            queue.Enqueue(item);
-        }
-
-        // 循环直到队列为空
-        while (queue.Count > 0)
-        {
-            // 从队列中取出当前节点
-            var currentItem = queue.Dequeue();
-
-            // 将当前节点返回
-            yield return currentItem;
-
-            // 获取当前节点的所有子节点
-            var children = selector(currentItem) ?? new List<Tree<T>>();
-
-            // 将所有子节点加入队列
-            foreach (var child in children)
-            {
-                // 执行平铺时的操作(如果有的话)
-                optionAction?.Invoke(child, currentItem);
-                queue.Enqueue(child);
-            }
-        }
-    }
-
     /// <summary>
     /// 平行集合转换成树形结构
     /// </summary>
@@ -250,10 +156,8 @@ public static class TreeExtensions
     /// <param name="pidSelector"></param>
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
-    public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, string>> idSelector, Expression<Func<T, string>> pidSelector, string topValue = default) where T : ITreeParent<T>, ITreeChildren<T>
-    {
-        return ToTree<T, string>(source, idSelector, pidSelector, topValue);
-    }
+    public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, string>> idSelector, Expression<Func<T, string>> pidSelector, string topValue = null) where T : ITreeParent<T>, ITreeChildren<T>
+        => ToTree<T, string>(source, idSelector, pidSelector, topValue);
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -265,9 +169,7 @@ public static class TreeExtensions
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
     public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, int>> idSelector, Expression<Func<T, int>> pidSelector, int topValue = 0) where T : ITreeParent<T>, ITreeChildren<T>
-    {
-        return ToTree<T, int>(source, idSelector, pidSelector, topValue);
-    }
+        => ToTree<T, int>(source, idSelector, pidSelector, topValue);
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -279,9 +181,7 @@ public static class TreeExtensions
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
     public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, long>> idSelector, Expression<Func<T, long>> pidSelector, long topValue = 0) where T : ITreeParent<T>, ITreeChildren<T>
-    {
-        return ToTree<T, long>(source, idSelector, pidSelector, topValue);
-    }
+        =>ToTree<T, long>(source, idSelector, pidSelector, topValue);
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -293,9 +193,7 @@ public static class TreeExtensions
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
     public static List<T> ToTree<T>(this IEnumerable<T> source, Expression<Func<T, Guid>> idSelector, Expression<Func<T, Guid>> pidSelector, Guid topValue = default) where T : ITreeParent<T>, ITreeChildren<T>
-    {
-        return ToTree<T, Guid>(source, idSelector, pidSelector, topValue);
-    }
+        =>ToTree<T, Guid>(source, idSelector, pidSelector, topValue);
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -308,21 +206,9 @@ public static class TreeExtensions
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
     public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where T : ITreeParent<T>, ITreeChildren<T> where TKey : IComparable
-    {
-        if (source is IQueryable<T> queryable)
-        {
-            source = queryable.ToList();
-        }
-
-        if (idSelector.Body.ToString() == pidSelector.Body.ToString())
-        {
-            throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
-        }
-
-        var pidFunc = pidSelector.Compile();
-        var idFunc = idSelector.Compile();
-        return BuildTree(source.Where(t => t != null), idFunc, pidFunc, topValue).ToList();
-    }
+        => idSelector.Body.ToString() != pidSelector.Body.ToString()
+            ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList()
+            : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -331,9 +217,7 @@ public static class TreeExtensions
     /// <param name="source"></param>
     /// <returns></returns>
     public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, int>
-    {
-        return ToTree<T, int>(source);
-    }
+        =>ToTree<T, int>(source);
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -343,16 +227,8 @@ public static class TreeExtensions
     /// <param name="source"></param>
     /// <param name="topValue"></param>
     /// <returns></returns>
-    public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, TKey? topValue = null) where T : class, ITreeEntity<T, TKey> where TKey : struct, IComparable
-    {
-        if (source is IQueryable<T> queryable)
-        {
-            source = queryable.ToList();
-        }
-
-        var list = source.Where(t => t != null).ToList();
-        return BuildTree(list, topValue).ToList();
-    }
+    public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, TKey? topValue = null) where T : class, ITreeEntity<T, TKey> where TKey : struct, IComparable 
+        => BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -364,23 +240,10 @@ public static class TreeExtensions
     /// <param name="pidSelector"></param>
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
-    public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey?>> pidSelector, TKey? topValue = default) where T : ITreeChildren<T> where TKey : struct
-    {
-        if (source is IQueryable<T> queryable)
-        {
-            source = queryable.ToList();
-        }
-
-        if (idSelector.Body.ToString() == pidSelector.Body.ToString())
-        {
-            throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
-        }
-
-        var pidFunc = pidSelector.Compile();
-        var idFunc = idSelector.Compile();
-        source = source.Where(t => t != null).ToList();
-        return BuildTree(source, idFunc, pidFunc, topValue).ToList();
-    }
+    public static List<T> ToTree<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey?>> pidSelector, TKey? topValue = null) where T : ITreeChildren<T> where TKey : struct
+        => idSelector.Body.ToString() != pidSelector.Body.ToString()
+            ? BuildTree(source.Enumerable2NonNullList(), idSelector.Compile(), pidSelector.Compile(), topValue).ToList()
+            : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
 
     private static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, Func<T, TKey> idSelector, Func<T, TKey> pidSelector, TKey topValue = default) where T : ITreeChildren<T> where TKey : IComparable
     {
@@ -389,7 +252,7 @@ public static class TreeExtensions
         var list = source as ICollection<T> ?? source.ToList();
         foreach (var item in list.Where(item => !childrenLookup.ContainsKey(idSelector(item))))
         {
-            childrenLookup[idSelector(item)] = new List<T>();
+            childrenLookup[idSelector(item)] = [];
         }
 
         // 构建树结构
@@ -432,15 +295,11 @@ public static class TreeExtensions
         }
     }
 
-    internal static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, TKey? topValue = default) where T : ITreeEntity<T, TKey> where TKey : struct, IComparable
-    {
-        return BuildTree(source, t => t.Id, t => t.ParentId, topValue);
-    }
+    internal static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, TKey? topValue = null) where T : ITreeEntity<T, TKey> where TKey : struct, IComparable 
+        => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
 
-    internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, string topValue = null) where T : ITreeEntity<T>
-    {
-        return BuildTree(source, t => t.Id, t => t.ParentId, topValue);
-    }
+    internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, string topValue = null) where T : ITreeEntity<T> 
+        => BuildTree(source, t => t.Id, t => t.ParentId, topValue);
 
     internal static IEnumerable<T> BuildTree<T>(IEnumerable<T> source, T parent) where T : ITreeEntity<T>
     {
@@ -448,15 +307,11 @@ public static class TreeExtensions
         var childrenLookup = new NullableDictionary<string, List<T>>();
         var list = source as ICollection<T> ?? source.ToList();
         foreach (var item in list.Where(item => !childrenLookup.ContainsKey(item.Id)))
-        {
-            childrenLookup[item.Id] = new List<T>();
-        }
+            childrenLookup[item.Id] = [];
 
         // 构建树结构
         foreach (var item in list.Where(item => !string.IsNullOrEmpty(item.ParentId) && childrenLookup.ContainsKey(item.ParentId)))
-        {
             childrenLookup[item.ParentId].Add(item);
-        }
 
         // 找到根节点,即没有父节点的节点
         foreach (var root in list.Where(x => x.Id == parent.Id))
@@ -478,9 +333,7 @@ public static class TreeExtensions
                     {
                         // 如果子节点实现了ITreeParent接口,则设置其Parent属性
                         if (child is ITreeParent<T> tree)
-                        {
                             tree.Parent = current;
-                        }
 
                         // 将子节点入队以继续处理
                         queue.Enqueue(child);
@@ -492,14 +345,14 @@ public static class TreeExtensions
         }
     }
 
-    private static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, Func<T, TKey> idSelector, Func<T, TKey?> pidSelector, TKey? topValue = default) where T : ITreeChildren<T> where TKey : struct
+    private static IEnumerable<T> BuildTree<T, TKey>(IEnumerable<T> source, Func<T, TKey> idSelector, Func<T, TKey?> pidSelector, TKey? topValue = null) where T : ITreeChildren<T> where TKey : struct
     {
         // 创建一个字典,用于快速查找节点的子节点
         var childrenLookup = new NullableDictionary<TKey, List<T>>();
         var list = source as ICollection<T> ?? source.ToList();
         foreach (var item in list.Where(item => !childrenLookup.ContainsKey(idSelector(item))))
         {
-            childrenLookup[idSelector(item)] = new List<T>();
+            childrenLookup[idSelector(item)] = [];
         }
 
         // 构建树结构
@@ -553,17 +406,13 @@ public static class TreeExtensions
     /// <param name="topValue">根对象parentId的值</param>
     /// <returns></returns>
     public static List<Tree<T>> ToTreeGeneral<T, TKey>(this IEnumerable<T> source, Expression<Func<T, TKey>> idSelector, Expression<Func<T, TKey>> pidSelector, TKey topValue = default) where TKey : IComparable
-    {
-        if (idSelector.Body.ToString() == pidSelector.Body.ToString())
-        {
-            throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
-        }
-
-        var pidFunc = pidSelector.Compile();
-        var idFunc = idSelector.Compile();
-        var list = source.Where(t => t != null).ToList();
-        return BuildTreeGeneral(list, idFunc, pidFunc, topValue).ToList();
-    }
+        => idSelector.Body.ToString() != pidSelector.Body.ToString()
+            ? BuildTreeGeneral(
+                source.Where(t => t != null).ToList(), 
+                idSelector.Compile(), 
+                pidSelector.Compile(),
+                topValue).ToList()
+            : throw new ArgumentException("idSelector和pidSelector不应该为同一字段!");
 
     private static IEnumerable<Tree<T>> BuildTreeGeneral<T, TKey>(List<T> list, Func<T, TKey> idSelector, Func<T, TKey> pidSelector, TKey parent) where TKey : IComparable
     {
@@ -571,7 +420,7 @@ public static class TreeExtensions
         var lookup = new Dictionary<TKey, List<Tree<T>>>();
         foreach (var item in list.Where(item => !lookup.ContainsKey(idSelector(item))))
         {
-            lookup[idSelector(item)] = new List<Tree<T>>();
+            lookup[idSelector(item)] = [];
         }
 
         // 构建树结构
@@ -612,57 +461,68 @@ public static class TreeExtensions
     /// <summary>
     /// 所有子级
     /// </summary>
-    public static ICollection<T> AllChildren<T>(this T tree) where T : ITreeChildren<T> => GetChildren(tree, c => c.Children);
+    public static ICollection<T> AllChildren<T>(this T tree) where T : ITreeChildren<T> 
+        => GetChildren(tree, c => c.Children);
 
     /// <summary>
     /// 所有子级
     /// </summary>
-    public static ICollection<T> AllChildren<T>(this T tree, Func<T, IEnumerable<T>> selector) where T : ITreeChildren<T> => GetChildren(tree, selector);
+    public static ICollection<T> AllChildren<T>(this T tree, Func<T, IEnumerable<T>> selector) where T : ITreeChildren<T> 
+        => GetChildren(tree, selector);
 
     /// <summary>
     /// 所有子级
     /// </summary>
-    public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree) => GetChildren(tree, c => c.Children);
+    public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree) 
+        => GetChildren(tree, c => c.Children);
 
     /// <summary>
     /// 所有子级
     /// </summary>
-    public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree, Func<Tree<T>, IEnumerable<Tree<T>>> selector) => GetChildren(tree, selector);
+    public static ICollection<Tree<T>> AllChildren<T>(this Tree<T> tree, Func<Tree<T>, IEnumerable<Tree<T>>> selector) 
+        => GetChildren(tree, selector);
 
     /// <summary>
     /// 所有父级
     /// </summary>
-    public static List<T> AllParent<T>(this T tree) where T : class, ITreeParent<T> => GetParents(tree, c => c.Parent);
+    public static List<T> AllParent<T>(this T tree) where T : class, ITreeParent<T> 
+        => GetParents(tree, c => c.Parent);
 
     /// <summary>
     /// 所有父级
     /// </summary>
-    public static List<T> AllParent<T>(this T tree, Func<T, T> selector) where T : class, ITreeParent<T> => GetParents(tree, selector);
+    public static List<T> AllParent<T>(this T tree, Func<T, T> selector) where T : class, ITreeParent<T> 
+        => GetParents(tree, selector);
 
     /// <summary>
     /// 所有父级
     /// </summary>
-    public static List<Tree<T>> AllParent<T>(this Tree<T> tree, Func<Tree<T>, Tree<T>> selector) => GetParents(tree, selector);
+    public static List<Tree<T>> AllParent<T>(this Tree<T> tree, Func<Tree<T>, Tree<T>> selector) 
+        => GetParents(tree, selector);
 
     /// <summary>
     /// 是否是根节点
     /// </summary>
-    public static bool IsRoot<T>(this ITreeParent<T> tree) where T : ITreeParent<T> => tree.Parent == null;
+    public static bool IsRoot<T>(this ITreeParent<T> tree) where T : ITreeParent<T> 
+        => tree.Parent == null;
 
     /// <summary>
     /// 是否是叶子节点
     /// </summary>
-    public static bool IsLeaf<T>(this ITreeChildren<T> tree) where T : ITreeChildren<T> => tree.Children?.Count == 0;
+    public static bool IsLeaf<T>(this ITreeChildren<T> tree) where T : ITreeChildren<T> 
+        => tree.Children?.Count == 0;
 
     /// <summary>
     /// 是否是根节点
     /// </summary>
-    public static bool IsRoot<T>(this Tree<T> tree) => tree.Parent == null;
+    public static bool IsRoot<T>(this Tree<T> tree) 
+        => tree.Parent == null;
 
     /// <summary>
     /// 是否是叶子节点
     /// </summary>
-    public static bool IsLeaf<T>(this Tree<T> tree) => tree.Children?.Count == 0;
+    public static bool IsLeaf<T>(this Tree<T> tree) 
+        => tree.Children?.Count == 0;
 
     /// <summary>
     /// 深度层级
@@ -670,9 +530,7 @@ public static class TreeExtensions
     public static int Level<T>(this T tree) where T : class, ITreeParent<T>
     {
         if (tree == null)
-        {
             throw new ArgumentNullException(nameof(tree), "当前节点不能为null");
-        }
 
         // 使用一个队列来存储待处理的节点
         var queue = new Queue<T>();
@@ -691,15 +549,11 @@ public static class TreeExtensions
 
                 // 如果当前节点是根节点,则返回当前层级
                 if (currentNode.Parent == null)
-                {
                     return level;
-                }
 
                 // 将当前节点的父节点入队
                 if (currentNode.Parent != null)
-                {
                     queue.Enqueue(currentNode.Parent);
-                }
             }
 
             // 完成当前层级的遍历,准备进入下一层级
@@ -713,12 +567,14 @@ public static class TreeExtensions
     /// <summary>
     /// 节点路径(UNIX路径格式,以“/”分隔)
     /// </summary>
-    public static string Path<T>(this T tree) where T : class, ITree<T> => GetFullPath(tree, t => t.Name);
+    public static string Path<T>(this T tree) where T : class, ITree<T> 
+        => GetFullPath(tree, t => t.Name);
 
     /// <summary>
     /// 节点路径(UNIX路径格式,以“/”分隔)
     /// </summary>
-    public static string Path<T>(this T tree, Func<T, string> selector) where T : class, ITreeParent<T> => GetFullPath(tree, selector);
+    public static string Path<T>(this T tree, Func<T, string> selector) where T : class, ITreeParent<T> 
+        => GetFullPath(tree, selector);
 
     /// <summary>
     /// 节点路径
@@ -735,12 +591,14 @@ public static class TreeExtensions
     /// <param name="selector">选择字段</param>
     /// <param name="separator">分隔符</param>
     /// <returns></returns>
-    public static string Path<T>(this T tree, Func<T, string> selector, string separator) where T : class, ITreeParent<T> => GetFullPath(tree, selector, separator);
+    public static string Path<T>(this T tree, Func<T, string> selector, string separator) where T : class, ITreeParent<T> 
+        => GetFullPath(tree, selector, separator);
 
     /// <summary>
     /// 根节点
     /// </summary>
-    public static T Root<T>(this T tree) where T : class, ITreeParent<T> => GetRoot(tree, t => t.Parent);
+    public static T Root<T>(this T tree) where T : class, ITreeParent<T> 
+        => GetRoot(tree, t => t.Parent);
 
     private static string GetFullPath<T>(T c, Func<T, string> selector, string separator = "/") where T : class, ITreeParent<T>
     {
@@ -774,29 +632,21 @@ public static class TreeExtensions
 
         // 使用一个集合来存储已访问的节点,以避免无限循环
         var visited = new HashSet<T>();
-        T currentNode = c;
+        var currentNode = c;
 
         // 向上遍历直到找到根节点
-        while (currentNode != null)
+        while (true)
         {
             // 如果当前节点已被访问,说明存在循环引用,抛出异常
             if (!visited.Add(currentNode))
-            {
                 throw new InvalidOperationException("节点存在循环引用");
-            }
 
             var parent = selector(currentNode);
-            if (parent == null)
-            {
-                // 找到了根节点
-                return currentNode;
-            }
-
-            currentNode = parent;
+            if (parent != null)
+                currentNode = parent;
+            else
+                return currentNode;// 找到了根节点
         }
-
-        // 如果currentNode为null,说明最初的节点c就是根节点
-        return c;
     }
 
     /// <summary>
@@ -808,9 +658,7 @@ public static class TreeExtensions
     private static List<T> GetChildren<T>(T t, Func<T, IEnumerable<T>> selector)
     {
         if (t == null || selector == null)
-        {
-            return new List<T>(); // 如果t或selector为null,则返回空列表
-        }
+            return []; // 如果t或selector为null,则返回空列表
 
         var list = new List<T>();
         var queue = new Queue<T>();
@@ -842,9 +690,7 @@ public static class TreeExtensions
     private static List<T> GetParents<T>(T t, Func<T, T> selector) where T : class
     {
         if (t == null || selector == null)
-        {
-            return new List<T>(); // 如果t或selector为null,则返回空列表
-        }
+            return []; // 如果t或selector为null,则返回空列表
 
         var parents = new List<T>();
         var current = t;
@@ -880,10 +726,8 @@ public static class TreeExtensionLong
     /// <typeparam name="T"></typeparam>
     /// <param name="source"></param>
     /// <returns></returns>
-    public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, long>
-    {
-        return source.ToTree<T, long>();
-    }
+    public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, long> 
+        => source.ToTree<T, long>();
 }
 
 /// <summary>
@@ -897,10 +741,8 @@ public static class TreeExtensionGuid
     /// <typeparam name="T"></typeparam>
     /// <param name="source"></param>
     /// <returns></returns>
-    public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, Guid>
-    {
-        return source.ToTree<T, Guid>();
-    }
+    public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T, Guid> 
+        => source.ToTree<T, Guid>();
 }
 
 /// <summary>
@@ -915,16 +757,8 @@ public static class TreeExtensionString
     /// <param name="source"></param>
     /// <param name="topValue"></param>
     /// <returns></returns>
-    public static List<T> ToTree<T>(this IEnumerable<T> source, string topValue) where T : class, ITreeEntity<T>
-    {
-        if (source is IQueryable<T> queryable)
-        {
-            source = queryable.ToList();
-        }
-
-        source = source.Where(t => t != null).ToList();
-        return TreeExtensions.BuildTree(source, topValue).ToList();
-    }
+    public static List<T> ToTree<T>(this IEnumerable<T> source, string topValue) where T : class, ITreeEntity<T> 
+        => TreeExtensions.BuildTree(source.Enumerable2NonNullList(), topValue).ToList();
 
     /// <summary>
     /// 平行集合转换成树形结构
@@ -933,13 +767,26 @@ public static class TreeExtensionString
     /// <param name="source"></param>
     /// <returns></returns>
     public static List<T> ToTree<T>(this IEnumerable<T> source) where T : class, ITreeEntity<T>
-    {
-        if (source is IQueryable<T> queryable)
-        {
-            source = queryable.ToList();
-        }
-
-        source = source.Where(t => t != null).ToList();
-        return source.Where(t => string.IsNullOrEmpty(t.ParentId)).SelectMany(parent => TreeExtensions.BuildTree(source, parent)).ToList();
+        => source.Enumerable2NonNullList()
+        .Where(t => string.IsNullOrEmpty(t.ParentId))
+        .SelectMany(parent => TreeExtensions.BuildTree(source, parent)).ToList();
+}
+file static class TreeExtensionCommon 
+{
+    /// <summary>
+    /// 将IEnumerable转换成不含null的List,若T为IQueryable,则将数据读取到内存
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    /// <param name="source"></param>
+    /// <returns></returns>
+    public static List<T> Enumerable2NonNullList<T>(this IEnumerable<T> source)
+    {
+        source = source is IQueryable<T> queryable 
+            ? queryable.AsEnumerable() 
+            : source;
+        return (typeof(T).IsValueType
+                ? source
+                : source.Where(t => t != null))
+            .ToList();
     }
 }