diff --git a/DynamicEnums/DynamicEnum.cs b/DynamicEnums/DynamicEnum.cs index dad3182..893c580 100644 --- a/DynamicEnums/DynamicEnum.cs +++ b/DynamicEnums/DynamicEnum.cs @@ -5,6 +5,10 @@ using System.Linq; using System.Numerics; using System.Reflection; +#if NET6_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + namespace DynamicEnums { /// /// A dynamic enum is a class that represents enum-like single-instance value behavior with additional capabilities, including dynamic addition of new arbitrary values. @@ -100,7 +104,11 @@ namespace DynamicEnums { /// The type to add this value to /// The newly created enum value /// Thrown if the name or value passed are already present - public static T Add(string name, BigInteger value) where T : DynamicEnum { + public static T Add< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(string name, BigInteger value) where T : DynamicEnum { var storage = DynamicEnum.GetStorage(typeof(T)); // cached parsed values and names might be incomplete with new values @@ -126,7 +134,11 @@ namespace DynamicEnums { /// The name of the enum value to add /// The type to add this value to /// The newly created enum value - public static T AddValue(string name) where T : DynamicEnum { + public static T AddValue< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(string name) where T : DynamicEnum { BigInteger value = 0; while (DynamicEnum.IsDefined(typeof(T), value)) value++; @@ -141,7 +153,11 @@ namespace DynamicEnums { /// The name of the enum value to add /// The type to add this value to /// The newly created enum value - public static T AddFlag(string name) where T : DynamicEnum { + public static T AddFlag< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(string name) where T : DynamicEnum { BigInteger value = 1; while (DynamicEnum.IsDefined(typeof(T), value)) value <<= 1; @@ -190,7 +206,11 @@ namespace DynamicEnums { /// The combined flags whose individual flags to return. /// The type of enum. /// All of the unique flags that make up . - public static IEnumerable GetUniqueFlags(T combinedFlag) where T : DynamicEnum { + public static IEnumerable GetUniqueFlags< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(T combinedFlag) where T : DynamicEnum { // we can't use the same method here as EnumHelper.GetUniqueFlags since DynamicEnum doesn't guarantee sorted values var max = DynamicEnum.GetValues().Max(DynamicEnum.GetValue); var uniqueFlag = BigInteger.One; @@ -211,7 +231,11 @@ namespace DynamicEnums { /// The right value /// The type of the values /// The bitwise OR (|) combination - public static T Or(T left, T right) where T : DynamicEnum { + public static T Or< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(T left, T right) where T : DynamicEnum { var cache = DynamicEnum.GetStorage(typeof(T)).OrCache; if (!cache.TryGetValue((left, right), out var ret)) { ret = DynamicEnum.GetEnumValue(DynamicEnum.GetValue(left) | DynamicEnum.GetValue(right)); @@ -227,7 +251,11 @@ namespace DynamicEnums { /// The right value /// The type of the values /// The bitwise AND (&) combination - public static T And(T left, T right) where T : DynamicEnum { + public static T And< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(T left, T right) where T : DynamicEnum { var cache = DynamicEnum.GetStorage(typeof(T)).AndCache; if (!cache.TryGetValue((left, right), out var ret)) { ret = DynamicEnum.GetEnumValue(DynamicEnum.GetValue(left) & DynamicEnum.GetValue(right)); @@ -243,7 +271,11 @@ namespace DynamicEnums { /// The right value /// The type of the values /// The bitwise XOR (^) combination - public static T Xor(T left, T right) where T : DynamicEnum { + public static T Xor< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(T left, T right) where T : DynamicEnum { var cache = DynamicEnum.GetStorage(typeof(T)).XorCache; if (!cache.TryGetValue((left, right), out var ret)) { ret = DynamicEnum.GetEnumValue(DynamicEnum.GetValue(left) ^ DynamicEnum.GetValue(right)); @@ -258,7 +290,11 @@ namespace DynamicEnums { /// The value /// The type of the values /// The bitwise NEG (~) value - public static T Neg(T value) where T : DynamicEnum { + public static T Neg< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(T value) where T : DynamicEnum { var cache = DynamicEnum.GetStorage(typeof(T)).NegCache; if (!cache.TryGetValue(value, out var ret)) { ret = DynamicEnum.GetEnumValue(~DynamicEnum.GetValue(value)); @@ -282,7 +318,11 @@ namespace DynamicEnums { /// The value whose dynamic enum value to get /// The type that the returned dynamic enum should have /// The defined or combined dynamic enum value - public static T GetEnumValue(BigInteger value) where T : DynamicEnum { + public static T GetEnumValue< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(BigInteger value) where T : DynamicEnum { return (T) DynamicEnum.GetEnumValue(typeof(T), value); } @@ -292,7 +332,11 @@ namespace DynamicEnums { /// The type that the returned dynamic enum should have /// The value whose dynamic enum value to get /// The defined or combined dynamic enum value - public static DynamicEnum GetEnumValue(Type type, BigInteger value) { + public static DynamicEnum GetEnumValue( + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + Type type, BigInteger value) { var storage = DynamicEnum.GetStorage(type); // get the defined value if it exists @@ -315,7 +359,11 @@ namespace DynamicEnums { /// The string to parse into a dynamic enum value /// The type of the dynamic enum value to parse /// The parsed enum value, or null if parsing fails - public static T Parse(string strg) where T : DynamicEnum { + public static T Parse< + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + T>(string strg) where T : DynamicEnum { return (T) DynamicEnum.Parse(typeof(T), strg); } @@ -327,7 +375,11 @@ namespace DynamicEnums { /// The type of the dynamic enum value to parse /// The string to parse into a dynamic enum value /// The parsed enum value, or null if parsing fails - public static DynamicEnum Parse(Type type, string strg) { + public static DynamicEnum Parse( + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + Type type, string strg) { var cache = DynamicEnum.GetStorage(type).ParseCache; if (!cache.TryGetValue(strg, out var cached)) { BigInteger? accum = null; @@ -375,7 +427,11 @@ namespace DynamicEnums { return storage; } - private static DynamicEnum Construct(Type type, string name, BigInteger value) { + private static DynamicEnum Construct( + #if NET6_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + #endif + Type type, string name, BigInteger value) { return (DynamicEnum) Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new object[] {name, value}, CultureInfo.InvariantCulture); }