/// <summary> /// 返回 <paramref name="type"/> 中与指定标识符相关的静态方法切换器。 /// 多次获取特定类型中同一标识符的方法切换器,必须使用相同的 /// <typeparamref name="TDelegate"/> 和 <paramref name="index"/>。 /// </summary> /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam> /// <param name="type">在其中查找静态方法的类型。</param> /// <param name="index">方法的关键参数索引。</param> /// <param name="id">方法切换器的标识符。</param> /// <returns><paramref name="type"/> 中与指定标识符相关的静态方法切换器。</returns> public static TDelegate GetSwitcher <TDelegate>(Type type, int index, string id) where TDelegate : class { ExceptionHelper.CheckArgumentNull(type, "type"); Type dlgType = typeof(TDelegate); ExceptionHelper.CheckDelegateType(dlgType, "TDelegate"); Dictionary <Type, Delegate> methods = GetMethods <TDelegate>(type, id, index, true); MethodInfo invoke = dlgType.GetMethod("Invoke"); // 构造委托。 ParameterExpression[] paramList = invoke.GetParameters().ToExpressions(); // 取得关键类型。 Expression getType = Expression.Call(paramList[index], typeof(object).GetMethod("GetType")); // 从字典取得相应委托。 Expression getDlg = Expression.Invoke( Expression.Constant((Func <Dictionary <Type, Delegate>, Type, Delegate>)GetMethod), Expression.Constant(methods), getType); getDlg = Expression.Convert(getDlg, dlgType); // 调用委托。 Expression invokeDlg = Expression.Invoke(getDlg, paramList); return(Expression.Lambda <TDelegate>(invokeDlg, paramList).Compile() as TDelegate); }
/// <summary> /// 使用包含属性的对象和属性信息,初始化 <see cref="MemberAccessor<T>"/> 类的新实例, /// 表示指定的实例属性。 /// </summary> /// <param name="target">包含实例属性的对象。</param> /// <param name="property">要访问的实例属性。</param> /// <param name="nonPublic">指示是否应访问非公共属性。 /// 如果要访问非公共属性,则为 <c>true</c>;否则为 <c>false</c>。</param> public MemberAccessor(object target, PropertyInfo property, bool nonPublic) { ExceptionHelper.CheckArgumentNull(target, "target"); ExceptionHelper.CheckArgumentNull(property, "property"); this.name = property.Name; Init(property, target, nonPublic); }
/// <summary> /// 对指定类型执行基本的类型转换判断,包括转换为 object 和 null 转换。 /// 基本类型转换失败时,保证 value != null,nonNullableType != null。 /// </summary> /// <param name="value">要转换的对象。</param> /// <param name="conversionType">要返回的对象的类型。</param> /// <param name="nonNullableType"><paramref name="value"/> 对应的 non-nullable-type。</param> /// <returns>如果基本类型转换成功,则为 <c>true</c>;否则为 <c>false</c>。</returns> private static bool BasicChangeType(ref object value, Type conversionType, out Type nonNullableType) { ExceptionHelper.CheckArgumentNull(conversionType, "conversionType"); if (conversionType.IsByRef) { conversionType = conversionType.GetElementType(); } // 总是可以转换为 Object。 if (conversionType == typeof(object)) { nonNullableType = null; return(true); } // value 为 null 的情况。 bool nullableCType = TypeExt.IsNullableType(conversionType, out nonNullableType); if (value == null) { if (conversionType.IsValueType && !nullableCType) { throw ExceptionHelper.CannotCastNullToValueType(); } return(true); } return(false); }
/// <summary> /// 返回指定对象中与指定标识符相关的实例方法切换器。 /// 多次获取特定类型中同一标识符的方法切换器,必须使用相同的 /// <typeparamref name="TDelegate"/> 和 <paramref name="index"/>。 /// </summary> /// <typeparam name="TDelegate">使用基类型调用方法的委托。</typeparam> /// <param name="target">实例方法的目标对象。</param> /// <param name="index">方法的关键参数索引。</param> /// <param name="id">方法切换器的标识符。</param> /// <returns>指定对象中与指定标识符相关的实例方法切换器。</returns> public static TDelegate GetSwitcher <TDelegate>(object target, int index, string id) where TDelegate : class { ExceptionHelper.CheckArgumentNull(target, "target"); Type dlgType = typeof(TDelegate); ExceptionHelper.CheckDelegateType(dlgType, "TDelegate"); Dictionary <Type, Delegate> methods = GetMethods <TDelegate>(target.GetType(), id, index, false); MethodInfo invoke = dlgType.GetMethod("Invoke"); // 构造委托。 ParameterExpression[] paramList = invoke.GetParameters().ToExpressions(); // 取得关键类型。 Expression getType = Expression.Call(paramList[index], typeof(object).GetMethod("GetType")); // 从字典取得相应委托。 Expression getDlg = Expression.Invoke( Expression.Constant((Func <Dictionary <Type, Delegate>, Type, Delegate>)GetMethod), Expression.Constant(methods), getType); // 调用实例方法委托。 Type insDlgType = GetInstanceDlgType(dlgType); getDlg = Expression.Convert(getDlg, insDlgType); Expression[] invokeArgs = new Expression[paramList.Length + 1]; invokeArgs[0] = Expression.Constant(target); for (int i = 0; i < paramList.Length; i++) { invokeArgs[i + 1] = paramList[i]; } // 调用委托。 Expression invokeDlg = Expression.Invoke(getDlg, invokeArgs); return(Expression.Lambda <TDelegate>(invokeDlg, paramList).Compile() as TDelegate); }
/// <summary> /// 使用包含属性的对象和字段信息,初始化 <see cref="MemberAccessor<T>"/> 类的新实例, /// 表示指定的实例字段。 /// </summary> /// <param name="target">包含实例字段的对象。</param> /// <param name="field">要访问的实例字段。</param> public MemberAccessor(object target, FieldInfo field) { ExceptionHelper.CheckArgumentNull(target, "target"); ExceptionHelper.CheckArgumentNull(field, "field"); this.name = field.Name; Init(field, target); }
public static void Times(this uint source, Action <uint> action) { ExceptionHelper.CheckArgumentNull(action, "action"); for (uint i = 0; i < source; i++) { action(i); } }
public static IEnumerable <T> Times <T>(this uint source, Func <uint, T> value) { ExceptionHelper.CheckArgumentNull(value, "value"); for (uint i = 0; i < source; i++) { yield return(value(i)); } }
public static void Times(this ulong source, Action action) { ExceptionHelper.CheckArgumentNull(action, "action"); for (ulong i = 0; i < source; i++) { action(); } }
/// <summary> /// 从此实例检索子字符串。子字符串从指定的字符位置开始且具有指定的长度。 /// 如果 <paramref name="startIndex"/> 小于 <c>0</c>, /// 那么表示从字符串结束位置向前计算的位置。 /// </summary> /// <param name="str">要检索子字符串的字符串实例。</param> /// <param name="startIndex">此示例中子字符串的起始字符位置(从零开始)。</param> /// <param name="length">子字符串中的字符数。</param> /// <returns>与此实例中在 <paramref name="startIndex"/> 处开头、 /// 长度为 <paramref name="length"/> 的子字符串等效的一个字符串, /// 如果 <paramref name="startIndex"/> 等于此实例的长度或 /// <paramref name="length"/> 为零,则为空字符串("")。</returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> 加 <paramref name="length"/> /// 之和指示的位置不在此实例中。</exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> 小于负的此实例的长度。</exception> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="length"/> 小于零。</exception> /// <seealso cref="System.String.Substring(int,int)"/> /// <overloads> /// <summary> /// 从此实例检索子字符串。 /// </summary> /// </overloads> public static string SubstringEx(this string str, int startIndex, int length) { ExceptionHelper.CheckArgumentNull(str, "str"); if (startIndex < 0) { startIndex += str.Length; } return(str.Substring(startIndex, length)); }
/// <summary> /// 检查委托的类型是否合法。 /// </summary> /// <param name="type">委托的类型。</param> /// <param name="paramName">参数的名称。</param> internal static void CheckDelegateType(Type type, string paramName) { ExceptionHelper.CheckArgumentNull(type, paramName); Type baseType = type.BaseType; if (baseType != typeof(MulticastDelegate)) { throw ExceptionHelper.MustBeDelegate(paramName); } }
public static void Times(this ulong source, Func <bool> func) { ExceptionHelper.CheckArgumentNull(func, "func"); for (ulong i = 0; i < source; i++) { if (!func()) { break; } } }
/// <summary> /// 将特定操作执行多次,并可以随时停止执行。 /// </summary> /// <param name="source">要执行操作的次数。只有大于 0 时才有效。 /// </param> /// <param name="func">要执行的操作,参数为当前执行的次数。返回 /// <c>true</c> 则继续执行,<c>false</c> 则停止。</param> public static void Times(this int source, Func <int, bool> func) { ExceptionHelper.CheckArgumentNull(func, "func"); for (int i = 0; i < source; i++) { if (!func(i)) { break; } } }
/// <summary> /// 对序列中的所有元素依次执行操作。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。</typeparam> /// <param name="source">包含要应用操作的元素的 /// <see cref="System.Collections.Generic.IEnumerable<T>"/>。 /// </param> /// <param name="action">用于对每个元素执行的操作的函数。</param> /// <returns>类型为 <see cref="System.Collections.Generic.IEnumerable<T>"/> /// 的输入序列。</returns> /// <overloads> /// <summary> /// 对序列中的所有元素依次执行操作。 /// </summary> /// </overloads> public static IEnumerable <TSource> Each <TSource>( this IEnumerable <TSource> source, Action <TSource> action) { ExceptionHelper.CheckArgumentNull(source, "source"); ExceptionHelper.CheckArgumentNull(action, "action"); foreach (TSource obj in source) { action(obj); } return(source); }
/// <summary> /// 从此实例检索子字符串。子字符串从指定的字符位置开始到字符串的结尾。 /// 如果 <paramref name="startIndex"/> 小于 <c>0</c>, /// 那么表示从字符串结束位置向前计算的位置。 /// </summary> /// <param name="str">要检索子字符串的字符串实例。</param> /// <param name="startIndex">此示例中子字符串的起始字符位置(从零开始)。</param> /// <returns>与此实例中在 <paramref name="startIndex"/> /// 处开头到字符串结尾的子字符串等效的一个字符串, /// 如果 <paramref name="startIndex"/> 等于此实例的长度或大于等于字符串的长度, /// 则为空字符串("")。</returns> /// <exception cref="System.ArgumentOutOfRangeException"> /// <paramref name="startIndex"/> 指示的位置不在此实例中。</exception> public static string Slice(this string str, int startIndex) { ExceptionHelper.CheckArgumentNull(str, "str"); if (startIndex < 0) { startIndex += str.Length; } if (startIndex < str.Length) { return(str.Substring(startIndex)); } return(string.Empty); }
/// <summary> /// 通过使用指定的 /// <see cref="System.Collections.Generic.IEqualityComparer<T>"/> /// 对值进行比较返回序列中的重复元素。重复多次的元素只得到其中的第一个。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。 /// </typeparam> /// <param name="source">要从中得到重复元素的序列。</param> /// <param name="comparer">用于比较值的 /// <see cref="System.Collections.Generic.IEqualityComparer<T>"/>。</param> /// <returns>一个序列,包含源序列中的重复元素。</returns> public static IEnumerable <TSource> Iterative <TSource>( this IEnumerable <TSource> source, IEqualityComparer <TSource> comparer) { ExceptionHelper.CheckArgumentNull(source, "source"); HashSet <TSource> set = new HashSet <TSource>(comparer); foreach (TSource item in source) { if (!set.Add(item)) { yield return(item); } } }
/// <summary> /// 根据给定的类型数组推断泛型方法的类型参数。 /// </summary> /// <param name="method">要推断类型参数的泛型方法。</param> /// <param name="types">实参参数数组。</param> /// <returns>如果成功推断泛型方法的类型参数,则为类型参数数组; /// 如果推断失败,则为 <c>null</c>。</returns> /// <exception cref="System.InvalidOperationException"> /// 当前 <see cref="System.Reflection.MethodBase"/> 不表示泛型方法定义。 /// 也就是说,<see cref="System.Reflection.MethodBase.IsGenericMethodDefinition "/> /// 返回 <c>false</c>。</exception> /// <exception cref="System.ArgumentNullException"><paramref name="method"/> 为 <c>null</c>。</exception> /// <exception cref="System.ArgumentNullException"><paramref name="types"/> 为 <c>null</c>。</exception> public static Type[] GenericArgumentsInferences(this MethodBase method, params Type[] types) { ExceptionHelper.CheckArgumentNull(method, "method"); ExceptionHelper.CheckArgumentNull(types, "types"); if (method.IsGenericMethodDefinition) { ParameterInfo[] parameters = method.GetParameters(); return(GenericArgumentsInferences(method, parameters, types)); } else { throw ExceptionHelper.NotGenericMethodDefinition(method, "GenericArgumentsInferences"); } }
/// <summary> /// 对序列中的所有元素依次执行操作,并可以随时停止。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。 /// </typeparam> /// <param name="source">包含要应用操作的元素的 /// <see cref="System.Collections.Generic.IEnumerable<T>"/>。 /// </param> /// <param name="func">用于对每个元素执行的操作的函数,返回 <c>true</c> /// 则继续执行操作,返回 <c>false</c> 则停止操作。</param> /// <returns>类型为 <see cref="System.Collections.Generic.IEnumerable<T>"/> /// 的输入序列。</returns> public static IEnumerable <TSource> Each <TSource>( this IEnumerable <TSource> source, Func <TSource, bool> func) { ExceptionHelper.CheckArgumentNull(source, "source"); ExceptionHelper.CheckArgumentNull(func, "func"); foreach (TSource obj in source) { if (!func(obj)) { break; } } return(source); }
/// <summary> /// 对序列中的所有元素依次执行操作。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。</typeparam> /// <param name="source">包含要应用操作的元素的 /// <see cref="System.Collections.Generic.IEnumerable<T>"/>。 /// </param> /// <param name="action">用于对每个元素执行的操作的函数。</param> /// <returns>类型为 <see cref="System.Collections.Generic.IEnumerable<T>"/> /// 的输入序列。</returns> public static IEnumerable <TSource> Each <TSource>( this IEnumerable <TSource> source, Action <TSource> action) { ExceptionHelper.CheckArgumentNull(source, "source"); ExceptionHelper.CheckArgumentNull(action, "action"); TSource[] list = source.ToArray(); int len = list.Length; for (int i = 0; i < len; i++) { action(list[i]); } return(list); }
/// <summary> /// 使用指定的关键参数索引和方法委托列表初始化 /// <see cref="MethodSwitcherManual<TDelegate>"/> 类的新实例。 /// </summary> /// <param name="idx">关键参数的索引。</param> /// <param name="methods">使用不同子类作为参数的方法列表。</param> /// <exception cref="System.ArgumentException"><typeparamref name="TDelegate"/> 不继承 /// <see cref="System.MulticastDelegate"/>。</exception> /// <exception cref="System.ArgumentOutOfRangeException"><paramref name="idx"/> /// 小于零或者大于等于 <typeparamref name="TDelegate"/> 的参数个数。</exception> /// <exception cref="System.ArgumentNullException"><paramref name="methods"/> /// 中存在为 <c>null</c> 的方法。</exception> /// <exception cref="System.ArgumentException"><paramref name="methods"/> /// 中存在不与 <typeparamref name="TDelegate"/> 兼容的方法。</exception> public MethodSwitcherManual(int idx, params Delegate[] methods) { ExceptionHelper.CheckArgumentNull(methods, "methods"); Type dlgType = typeof(TDelegate); ExceptionHelper.CheckDelegateType(dlgType, "TDelegate"); ParameterInfo[] paramInfos = dlgType.GetMethod("Invoke").GetParameters(); int len = paramInfos.Length; if (idx < 0 || idx >= len) { throw ExceptionHelper.ArgumentOutOfRange("idx"); } keyIndex = idx; InitMethods(methods); BuildInvoke(paramInfos); }
/// <summary> /// 返回序列中满足指定条件的第一个元素的索引。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。</typeparam> /// <param name="source">要从中返回元素索引的 /// <see cref="System.Collections.Generic.IEnumerable<T>"/>。</param> /// <param name="predicate">用于测试每个元素是否满足条件的函数。</param> /// <returns>序列中通过指定谓词函数中的测试的第一个元素的索引。 /// 如果没有这样的元素,则返回 <c>-1</c>。</returns> /// <exception cref="System.ArgumentNullException"><paramref name="source"/> /// 或 <paramref name="predicate"/> 为 <c>null</c>。</exception> public static int FirstIndex <TSource>(this IEnumerable <TSource> source, Func <TSource, bool> predicate) { ExceptionHelper.CheckArgumentNull(source, "source"); ExceptionHelper.CheckArgumentNull(predicate, "predicate"); int idx = 0; foreach (TSource item in source) { if (predicate(item)) { return(idx); } idx++; } return(-1); }
/// <summary> /// 对序列中的所有元素依次执行操作,并可以随时停止。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。 /// </typeparam> /// <param name="source">包含要应用操作的元素的 /// <see cref="System.Collections.Generic.IEnumerable<T>"/>。 /// </param> /// <param name="func">用于对每个元素执行的操作的函数,返回 <c>true</c> /// 则继续执行操作,返回 <c>false</c> 则停止操作。</param> /// <returns>类型为 <see cref="System.Collections.Generic.IEnumerable<T>"/> /// 的输入序列。</returns> public static IEnumerable <TSource> Each <TSource>( this IEnumerable <TSource> source, Func <TSource, bool> func) { ExceptionHelper.CheckArgumentNull(source, "source"); ExceptionHelper.CheckArgumentNull(func, "func"); TSource[] list = source.ToArray(); int len = list.Length; for (int i = 0; i < len; i++) { if (!func(list[i])) { break; } } return(list); }
/// <summary> /// 从当前值递增(递减)到特定值并执行操作,可以随时停止执行操作。 /// </summary> /// <param name="source">要执行操作的起始值。</param> /// <param name="destination">要执行操作的目标值。</param> /// <param name="func">要执行的操作,参数为当前的值。返回 /// <c>true</c> 则继续执行,<c>false</c> 则停止。</param> public static void To(this long source, long destination, Func <long, bool> func) { ExceptionHelper.CheckArgumentNull(func, "func"); if (source < destination) { while (source <= destination && func(source)) { source++; } } else { while (source >= destination && func(source)) { source--; } } }
/// <summary> /// 使用包含实例属性或字段的类型和名称,初始化 <see cref="MemberAccessor<T>"/> 类的新实例, /// 表示指定的实例属性或字段。 /// </summary> /// <param name="targetType">包含实例属性或字段的类型。</param> /// <param name="name">实例属性或字段的名称。</param> /// <param name="nonPublic">指示是否应访问非公共实例属性或字段。 /// 如果要访问非公共实例属性或字段,则为 <c>true</c>;否则为 <c>false</c>。</param> public MemberAccessor(Type targetType, string name, bool nonPublic) { ExceptionHelper.CheckArgumentNull(targetType, "targetType"); this.name = name; PropertyInfo property = targetType.GetProperty(name, nonPublic ? NonPublic : Public); if (property != null) { Init(property, nonPublic); } else { FieldInfo field = targetType.GetField(name, nonPublic ? NonPublic : Public); if (field != null) { Init(field); } } }
/// <summary> /// 从当前值递增(递减)到指定值并执行指定操作。 /// </summary> /// <param name="source">要执行操作的起始值。</param> /// <param name="destination">要执行操作的目标值。</param> /// <param name="action">要执行的操作,参数为当前的值。</param> public static void To(this int source, int destination, Action <int> action) { ExceptionHelper.CheckArgumentNull(action, "action"); if (source < destination) { while (source <= destination) { action(source); source++; } } else { while (source >= destination) { action(source); source--; } } }
public static void To(this uint source, uint destination, Func <uint, bool> func) { ExceptionHelper.CheckArgumentNull(func, "func"); if (source < destination) { while (source < destination && func(source)) { source++; } func(source); } else { while (source > destination && func(source)) { source--; } func(source); } }
/// <summary> /// 从当前值递增(递减)到特定值并执行操作。 /// </summary> /// <param name="source">要执行操作的起始值。</param> /// <param name="destination">要执行操作的目标值。</param> /// <param name="action">要执行的操作,参数为当前的值。</param> public static void To(this long source, long destination, Action <long> action) { ExceptionHelper.CheckArgumentNull(action, "func"); if (source < destination) { while (source <= destination) { action(source); source++; } } else { while (source >= destination) { action(source); source--; } } }
public static void To(this ulong source, ulong destination, Action <ulong> action) { ExceptionHelper.CheckArgumentNull(action, "action"); if (source < destination) { while (source < destination) { action(source); source++; } action(source); } else { while (source > destination) { action(source); source--; } action(source); } }
public static void To(this uint source, uint destination, Action <uint> action) { ExceptionHelper.CheckArgumentNull(action, "func"); if (source < destination) { while (source < destination) { action(source); source++; } action(source); } else { while (source > destination) { action(source); source--; } action(source); } }
/// <summary> /// 通过使用指定的 /// <see cref="System.Collections.Generic.IEqualityComparer<T>"/> /// 对值进行比较返回序列中的重复元素。 /// </summary> /// <typeparam name="TSource"><paramref name="source"/> 中的元素的类型。 /// </typeparam> /// <param name="source">要从中得到重复元素的序列。</param> /// <param name="comparer">用于比较值的 /// <see cref="System.Collections.Generic.IEqualityComparer<T>"/>。</param> /// <returns>一个序列,包含源序列中的重复元素。</returns> public static IEnumerable <TSource> Iterative <TSource>( this IEnumerable <TSource> source, IEqualityComparer <TSource> comparer) { ExceptionHelper.CheckArgumentNull(source, "source"); Dictionary <TSource, bool> dict = new Dictionary <TSource, bool>(comparer); foreach (TSource item in source) { bool flag; if (dict.TryGetValue(item, out flag)) { if (flag) { yield return(item); dict[item] = false; } } else { dict.Add(item, true); } } }
/// <summary> /// 将一个或多个枚举常数的名称、描述或数字值的字符串表示转换成等效的枚举对象。 /// 一个参数指定该操作是否区分大小写。 /// </summary> /// <param name="enumType">枚举类型。</param> /// <param name="value">包含要转换的值或名称的字符串。</param> /// <param name="ignoreCase">若要忽略大小写则为 <c>true</c>; /// 否则为 <c>false</c>。</param> /// <returns><paramref name="enumType"/> 类型的对象,其值由 <paramref name="value"/> 表示。</returns> /// <exception cref="System.ArgumentNullException"> /// <paramref name="value"/> 为 <c>null</c>。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="enumType"/> 不是 <see cref="System.Enum"/>。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="value"/> 是空字符串 ("") 或只包含空白。</exception> /// <exception cref="System.ArgumentException"> /// <paramref name="value"/> 是一个名称,但不是为该枚举定义的命名常量之一。</exception> /// <exception cref="System.OverflowException"> /// <paramref name="value"/> 超出 <paramref name="enumType"/> /// 基础类型的范围。</exception> public static object ParseEx(Type enumType, string value, bool ignoreCase) { ExceptionHelper.CheckArgumentNull(enumType, "enumType"); ExceptionHelper.CheckArgumentNull(value, "value"); if (!enumType.IsEnum) { throw ExceptionHelper.MustBeEnum("enumType", enumType); } value = value.Trim(); if (value.Length == 0) { throw ExceptionHelper.MustContainEnumInfo("value"); } // 尝试对数字进行解析,这样可避免之后的字符串比较。 ulong tmpValue; if (ParseString(value, out tmpValue)) { return(Enum.ToObject(enumType, tmpValue)); } // 尝试对描述信息进行解析。 EnumCache cache = GetEnumCache(enumType); StringComparison comparison = ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; ulong valueUL = 0; int start = 0; do { // 去除前导空白。 while (char.IsWhiteSpace(value, start)) { start++; } int idx = value.IndexOf(',', start); if (idx < 0) { idx = value.Length; } int nIdx = idx - 1; // 去除后面的空白。 while (char.IsWhiteSpace(value, nIdx)) { nIdx--; } if (nIdx >= start) { string str = value.Substring(start, nIdx - start + 1); int j = 0; // 比较常数值的名称和描述信息,先比较名称,后比较描述信息。 for (; j < cache.Names.Length; j++) { if (string.Equals(str, cache.Names[j], comparison)) { // 与常数值匹配。 valueUL |= cache.Values[j]; break; } } if (j == cache.Names.Length && cache.HasDescription) { // 比较描述信息。 for (j = 0; j < cache.Descriptions.Length; j++) { if (string.Equals(str, cache.Descriptions[j], comparison)) { // 与描述信息匹配。 valueUL |= cache.Values[j]; break; } } } // 未识别的枚举值。 if (j == cache.Descriptions.Length) { // 尝试识别为数字。 if (ParseString(str, out tmpValue)) { valueUL |= tmpValue; } else { // 不能识别为数字。 throw ExceptionHelper.EnumValueNotFound(enumType, str); } } } start = idx + 1; } while (start < value.Length); return(Enum.ToObject(enumType, valueUL)); }