internal static bool TryCategoriesMapToEnum(Type enumType, string[] categories, out CategoryEnumMapType mapType) { // Operating under the assumption that the // the number of entries and categories // is normally small so avoiding a // HashSet alloc is the smart choice. // Could easily cache this result var allNames = Enum.GetNames(enumType); if (allNames.Length == 0) { mapType = default(CategoryEnumMapType); return(false); } if (allNames.Length < categories.Length) { mapType = default(CategoryEnumMapType); return(false); } bool exactNameMatch = true; for (var i = 0; i < categories.Length; i++) { var category = categories[i]; var found = false; for (var j = 0; j < allNames.Length; j++) { var enumName = allNames[j]; if (enumName.Equals(category, StringComparison.InvariantCultureIgnoreCase)) { found = true; break; } } if (!found) { exactNameMatch = false; } } if (exactNameMatch) { mapType = CategoryEnumMapType.ByName; return(true); } var enumIsByte = Enum.GetUnderlyingType(enumType) == typeof(byte); var enumIsSbyte = Enum.GetUnderlyingType(enumType) == typeof(sbyte); var enumIsShort = Enum.GetUnderlyingType(enumType) == typeof(short); var enumIsUshort = Enum.GetUnderlyingType(enumType) == typeof(ushort); var enumIsInt = Enum.GetUnderlyingType(enumType) == typeof(int); var enumIsUint = Enum.GetUnderlyingType(enumType) == typeof(uint); var enumIsLong = Enum.GetUnderlyingType(enumType) == typeof(long); var enumIsUlong = Enum.GetUnderlyingType(enumType) == typeof(ulong); bool ordinalMatch = true; for (var i = 0; i < categories.Length; i++) { var ordinal = i; if (enumIsByte) { if (!Enum.IsDefined(enumType, (byte)i)) { ordinalMatch = false; break; } continue; } if (enumIsSbyte) { if (!Enum.IsDefined(enumType, (sbyte)i)) { ordinalMatch = false; break; } continue; } if (enumIsShort) { if (!Enum.IsDefined(enumType, (short)i)) { ordinalMatch = false; break; } continue; } if (enumIsUshort) { if (!Enum.IsDefined(enumType, (ushort)i)) { ordinalMatch = false; break; } continue; } if (enumIsInt) { if (!Enum.IsDefined(enumType, (int)i)) { ordinalMatch = false; break; } continue; } if (enumIsUint) { if (!Enum.IsDefined(enumType, (uint)i)) { ordinalMatch = false; break; } continue; } if (enumIsLong) { if (!Enum.IsDefined(enumType, (long)i)) { ordinalMatch = false; break; } continue; } if (enumIsUlong) { if (!Enum.IsDefined(enumType, (ulong)i)) { ordinalMatch = false; break; } continue; } throw new Exception($"Couldn't make sense of enum type {enumType.Name} to map it"); } mapType = CategoryEnumMapType.ByOrdinal; return(ordinalMatch); }
internal static T Cast(Value value, CategoryEnumMapType enumMapConfig) => Delegate(value, enumMapConfig);