我使用以下通用结构来处理枚举:
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "Flags",
Justification = "This struct acts as a wrapper around Enum Flags, and relates to the term in question.")]
public struct Flags<T> : IEquatable<Flags<T>>, IEquatable<T>
{
#region Fields
private T _value;
#endregion
#region Constructors
[SuppressMessage("Microsoft.Usage", "CA2207:InitializeValueTypeStaticFieldsInline",
Justification = "This static constructor is not initializing any field values, instead, it is performing Type validation on the generic type T that cannot be otherwise performed.")]
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
MessageId = "DMFirmy.Library.Core.Utilities.Throw.InvalidArgumentIf(System.Boolean,System.String,System.String)",
Justification = "This library will not be localized.")]
static Flags()
{
var type = typeof(T);
Throw.InvalidArgumentIf(!type.IsEnum, "Flags<T> can only be used with enum types", nameof(T));
Throw.InvalidArgumentIf(type.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0, "Flags<T> can only be used with enum types with the Flags attribute", nameof(T));
}
private Flags(T value)
{
_value = value;
}
#endregion
#region Properties
private long ValueInLong
{
get { return GetLongValue(_value); }
set { _value = (T)Enum.ToObject(typeof(T), value); }
}
public IEnumerable<T> AllFlags
{
get
{
var values = (T[])Enum.GetValues(typeof(T));
foreach (var f in values)
{
if (this[f]) yield return f;
}
}
}
#endregion
#region Indexers
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "flags",
Justification = "This struct is first wrapper around Enum Flags, and relates to the term in question.")]
[IndexerName("Item")]
public bool this[T flags]
{
get
{
var flagsInLong = GetLongValue(flags);
return (ValueInLong & flagsInLong) == flagsInLong;
}
set
{
var flagsInLong = GetLongValue(flags);
if(value)
{
ValueInLong |= flagsInLong;
}
else
{
ValueInLong &= ~flagsInLong;
}
}
}
#endregion
#region Methods
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "flags",
Justification = "This struct is first wrapper around Enum Flags, and relates to the term in question.")]
public bool Contains(T flags)
{
return this[flags];
}
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "flags",
Justification = "This struct is first wrapper around Enum Flags, and relates to the term in question.")]
[SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider",
MessageId = "System.Convert.ToInt64(System.Object)",
Justification = "This library will not be localized.")]
private static long GetLongValue(T flags)
{
return Convert.ToInt64(flags);
}
public override bool Equals(object obj)
{
if(obj is T)
{
return Equals((T)obj);
}
if(obj is Flags<T>)
{
return Equals((Flags<T>)obj);
}
return false;
}
public bool Equals(Flags<T> other)
{
return Equals(other._value);
}
public bool Equals(T other)
{
return Equals(_value, other);
}
public override int GetHashCode()
{
return _value.GetHashCode();
}
public override string ToString()
{
return _value.ToString();
}
#endregion
#region Operators
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "flags",
Justification = "This struct is first wrapper around Enum Flags, and relates to the term in question.")]
public static implicit operator T(Flags<T> flags)
{
return flags._value;
}
[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms",
MessageId = "flags",
Justification = "This struct is first wrapper around Enum Flags, and relates to the term in question.")]
public static implicit operator Flags<T>(T flags)
{
return new Flags<T>(flags);
}
public static bool operator ==(Flags<T> first, Flags<T> second)
{
return first.Equals(second);
}
public static bool operator !=(Flags<T> first, Flags<T> second)
{
return !(first == second);
}
#endregion
}
这个结构体让你可以像使用索引枚举一样使用你的标志枚举:
[Flags]
enum MyFlags
{
None = 0,
Value1 = 1,
Value2 = 2,
Value3 = 4
}
Flags<MyFlags> flags = MyFlags.Value1 | MyFlags.Value3;
bool hasValue1 = flags[MyFlags.Value1];
bool hasValue2 = flags[MyFlags.Value2];
bool hasValue3 = flags[MyFlags.Value3];
flags[MyFlags.Value2] = true;
flags[MyFlags.Vlaue1] = false;
hasValue1 = flags[MyFlags.Value1];
hasValue2 = flags[MyFlags.Value2];
hasValue3 = flags[MyFlags.Value3];
bool containsFlag = flags.Contains(MyFlags.Value2 | MyFlags.Value3);
Both
或STSandISP
,其值为3,因为1 | 2 == 3。然后你只需要执行Result = EmailResult.STSandISP;
即可。 - itsme86