diff --git a/Apewer/TextUtility.cs b/Apewer/TextUtility.cs
index 5dd5fca..d5928b0 100644
--- a/Apewer/TextUtility.cs
+++ b/Apewer/TextUtility.cs
@@ -2,7 +2,6 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Runtime.InteropServices;
 using System.Text;
 using System.Text.RegularExpressions;
 
@@ -13,17 +12,27 @@ namespace Apewer
     public static class TextUtility
     {
 
+        const string LetterChars = LowerCase + UpperCase;
         const string BlankChars = "  \n\r\t\f\b\a"; // 在 IsBlank 和 Trim 中视为空白的字符。
         const string LineFeed = "\r\n"; // 换行符,由 ASCII 13 和 ASCII 10 组成。
-        const string SpaceDbc = " ";
-        const string SpaceSbc = " ";
-        const string LucidChars = "3456789acefhknpstwxyz";
-        const string KeyChars = "0123456789abcdefghijklmnopqrstuvwxyz";
-        const string HexChars = "0123456789abcdef";
-        const string NumericChars = "0123456789";
-        const string LowerChars = "abcdefghijklmnopqrstuvwxyz";
-        const string UpperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-        const string LetterChars = LowerChars + UpperChars;
+
+        /// 半角空格。
+        public const string Space = " ";
+
+        /// 全角空格。
+        public const string SpaceSbc = " ";
+
+        /// 十进制字符。
+        public const string Decimal = "0123456789";
+
+        /// 十六进制字符。
+        public const string Hexadecimal = "0123456789abcdef";
+
+        /// 小写字母。
+        public const string LowerCase = "abcdefghijklmnopqrstuvwxyz";
+
+        /// 大写字母。
+        public const string UpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
         /// UTF-8 BOM。
         public static byte[] Bom { get => new byte[] { 0xEF, 0xBB, 0xBF }; }
@@ -31,8 +40,11 @@ namespace Apewer
         /// CRLF。
         public const string CRLF = "\r\n";
 
+        /// CR。
+        public const char CR = '\r';
+
         /// LF。
-        public const string LF = "\n";
+        public const char LF = '\n';
 
         /// 长度为 0 的空字符串。
         public const string Empty = "";
@@ -220,9 +232,6 @@ namespace Apewer
             return new string(output);
         }
 
-        /// 获取指定长的的空格。
-        public static string Space(int length) => Duplicate(' ', length);
-
         /// 将文本以转换为字节数组。默认 Encoding 为 UTF-8。
         public static byte[] Bytes(string text, Encoding encoding = null)
         {
@@ -650,70 +659,107 @@ namespace Apewer
         public static string Random(int length, string pool = "0123456789abcdefghijklmnopqrstuvwxyz")
         {
             if (length < 1) return Empty;
-            if (IsEmpty(pool)) return Duplicate(SpaceDbc, length);
+            if (IsEmpty(pool)) return Duplicate(Space, length);
             var array = new char[length];
             var max = pool.Length - 1;
             for (var i = 0; i < length; i++) array[i] = pool[NumberUtility.Random(0, max)];
             return new string(array);
         }
 
-        /// 对字符串列表去重。指定 valid 参数时将去除无效字符串。
-        /// 
-        /// 
-        public static string[] Distinct(IEnumerable strings, bool valid = false)
+        /// 对字符串集合去重,同时去除 NULL 值和空字符串。
+        public static string[] Distinct(this IEnumerable strings) => Distinct(strings, false, false);
+
+        /// 对字符串集合去重。
+        /// 字符串集合。
+        /// 保留空字符串。
+        /// 保留 NULL 值。
+        public static string[] Distinct(this IEnumerable strings, bool withEmpty, bool withNull)
         {
             if (strings == null) return new string[0];
 
-            const string space = " ";
-            var hasNull = false;
-            var hasEmpty = false;
-            var hasSpace = false;
+            // 保留 NULL 和空字符串
+            var @null = false;
+            var empty = false;
 
-            var array = new ArrayBuilder();
-            foreach (var s in strings)
+            // 遍历,重组
+            var cache = new List();
+            if (strings is IList list)
             {
-                if (s == null)
-                {
-                    if (valid) continue;
-                    if (hasNull) continue;
-                    hasNull = true;
-                    array.Add(s);
-                    continue;
-                }
-                if (s == Empty)
+                var count = list.Count;
+                cache.Capacity = count;
+                for (var i = 0; i < count; i++)
                 {
-                    if (valid) continue;
-                    if (hasEmpty) continue;
-                    hasEmpty = true;
-                    array.Add(s);
-                    continue;
+                    var item = list[i];
+
+                    if (item == null)
+                    {
+                        if (withNull && !@null)
+                        {
+                            cache.Add(item);
+                            @null = true;
+                        }
+                        continue;
+                    }
+                    if (item == Empty)
+                    {
+                        if (withEmpty && !empty)
+                        {
+                            cache.Add(item);
+                            empty = true;
+                        }
+                        continue;
+                    }
+
+                    var added = false;
+                    for (var j = 0; j < cache.Count; j++)
+                    {
+                        if (cache[j] == item)
+                        {
+                            added = true;
+                            break;
+                        }
+                    }
+                    if (!added) cache.Add(item);
                 }
-                if (s == space)
+            }
+            else
+            {
+                foreach (var item in strings)
                 {
-                    if (valid) continue;
-                    if (hasSpace) continue;
-                    hasSpace = true;
-                    array.Add(s);
-                    continue;
-                }
+                    if (item == null)
+                    {
+                        if (withNull && !@null)
+                        {
+                            cache.Add(item);
+                            @null = true;
+                        }
+                        continue;
+                    }
+                    if (item == Empty)
+                    {
+                        if (withEmpty && !empty)
+                        {
+                            cache.Add(item);
+                            empty = true;
+                        }
+                        continue;
+                    }
 
-                var exist = false;
-                for (var i = 0; i < array.Length; i++)
-                {
-                    if (array[i] == s)
+                    var added = false;
+                    for (var j = 0; j < cache.Count; j++)
                     {
-                        exist = true;
-                        break;
+                        if (cache[j] == item)
+                        {
+                            added = true;
+                            break;
+                        }
                     }
+                    if (!added) cache.Add(item);
                 }
-                if (exist) continue;
-
-                array.Add(s);
             }
 
-            return array.Export();
+            return cache.ToArray();
         }
-
         /// 约束字符串中的字符,只包含指定的字符。
         public static string Restrict(string text, char[] chars)
         {
@@ -748,7 +794,7 @@ namespace Apewer
         public static string RestrictLetters(string text) => Restrict(text, LetterChars.ToCharArray());
 
         /// 约束字符串中的字符,只包含数字。
-        public static string RestrictNumeric(string text) => Restrict(text, NumericChars.ToCharArray());
+        public static string RestrictNumeric(string text) => Restrict(text, Decimal.ToCharArray());
 
         /// 返回此字符串的安全键副本,只保留数据记录主键中可能出现的字符,默认限制长度为 255 字符。
         public static string SafeKey(string text, int maxLength = 255)