C içinde bir bit maskesi kullanarak#
Şu var ki
int susan = 2; //0010
int bob = 4; //0100
int karen = 8; //1000
ve bir yöntem için parametre olarak 10 (8 2) geçer ve bu susan ve karen demek için çözmek istiyorum
10 1010 olduğunu biliyorum
ama nasıl bir mantık eğer belirli bir bit olarak işaretli olup olmadığını görmek için ne yapabilirim
if (condition_for_karen) // How to quickly check whether effective karen bit is 1
Şu an aklıma gelen bütün geçtim numarası olup olmadığını kontrol edin
14 // 1110
12 // 1100
10 // 1010
8 // 1000
Ben daha büyük bir sayı gerçek bit benim gerçek dünya senaryo, bu gibi pratik, ne daha iyi bir yolu kullanarak bir maske için sadece onay olsa da olmasa da ben karşılamak koşulu için sadece karen?
Sonra sağa sonra tekrar bit ilgileniyorum dışındaki temizlemek için değişen sol vites düşünemiyorum, ama bu da aşırı karmaşık görünüyor.
CEVAP
Bunu yapmak için geleneksel yolu enum
: Flags
niteliğini kullanmaktır
[Flags]
public enum Names
{
None = 0,
Susan = 1,
Bob = 2,
Karen = 4
}
Sonra aşağıdaki gibi belirli bir ad için kontrol ediyorum
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;
Mantıksal bit kombinasyonları hatırlamak zor olabilir, kendime hayat daha kolay FlagsHelper
a sınıfı* ile yaptım.:
// 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));
}
}
Bu bana yukarıdaki kod olarak: yeniden yazmak için izin verecek
Names names = Names.Susan | Names.Bob;
bool susanIsIncluded = FlagsHelper.IsSet(names, Names.Susan);
bool karenIsIncluded = FlagsHelper.IsSet(names, Names.Karen);
Ayrıca bunu yaparak: ayarlamak için Karen
ekleyebilirim unutmayın
FlagsHelper.Set(ref names, Names.Karen);
Ve benzer bir şekilde Susan
çıkarabilirim:
FlagsHelper.Unset(ref names, Names.Susan);
IsSet
yönteminin eşdeğer .NET 4.0: Enum.HasFlag
. Set
Unset
yöntemleri benzerleri var ama görünmüyor; ama bu sınıftaki bazı hak etti diyebilirim.
Not: Kullanarak çeteleler sadecegelenekselbu sorunu çözmede yol. Tamamen yukarıdaki kod tüm in yerine kullanmak çevirebilir ve sadece aynı işi görür.
'' ifadelerini kullanarak iç...
Nasıl düğmeye tıklama Parçaları içinde...
Yinelemeli olarak kullanarak wget için...
Herhangi bir parametre Listesi içinde ...
javascript içinde kullanarak jilet...