Cách truyền thống để làm điều này là sử dụng Flags
thuộc tính trên enum
:
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
Sau đó, bạn kiểm tra một tên cụ thể như sau:
Names names = Names.Susan | Names.Bob;
// evaluates to true
bool susanIsIncluded = (names & Names.Susan) != Names.None;
// evaluates to false
bool karenIsIncluded = (names & Names.Karen) != Names.None;
Các kết hợp theo từng bit logic có thể khó nhớ, vì vậy tôi tự làm cho cuộc sống trở nên dễ dàng hơn với một FlagsHelper
lớp học *:
// The casts to object in the below code are an unfortunate necessity due to
// C#'s restriction against a where T : Enum constraint. (There are ways around
// this, but they're outside the scope of this simple illustration.)
public static class FlagsHelper
{
public static bool IsSet<T>(T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
return (flagsValue & flagValue) != 0;
}
public static void Set<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue | flagValue);
}
public static void Unset<T>(ref T flags, T flag) where T : struct
{
int flagsValue = (int)(object)flags;
int flagValue = (int)(object)flag;
flags = (T)(object)(flagsValue & (~flagValue));
}
}
Điều này sẽ cho phép tôi viết lại đoạn mã trên dưới dạng:
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
Lưu ý rằng tôi cũng có thể thêm Karen
vào tập hợp bằng cách thực hiện điều này:
FlagsHelper.Set(ref names, Names.Karen);
Và tôi có thể xóa Susan
theo cách tương tự:
FlagsHelper.Unset(ref names, Names.Susan);
* Như Porges chỉ ra, tương đương với các IsSet
phương pháp trên đã tồn tại trong .NET 4.0: Enum.HasFlag
. Tuy nhiên Set
, Unset
các phương thức và phương thức dường như không tương đương nhau; vì vậy tôi vẫn muốn nói rằng lớp này có một số điểm đáng khen.
Lưu ý: Sử dụng enums chỉ là cách thông thường để giải quyết vấn đề này. Bạn hoàn toàn có thể dịch tất cả mã trên để sử dụng int thay thế và nó sẽ hoạt động tốt.