2011-03-21 27 views
6

en Böyle bir enum var diyelim dışlamak:C# enum

[Flags] 
public enum NotificationMethodType { 
    Email = 1, 
    Fax = 2, 
    Sms = 4 
} 

Ve en gibi bir değişken tanımlanmış olduğunu varsayalım:

NotificationMethodType types = (NotificationMethodType.Email | NotificationMethodType.Fax) 

nasıl NotificationMethodType tüm değerleri anlamaya emin "types" değişkeninde tanımlanmamış mı? Başka bir deyişle:

NotificationMethodType notAssigned = NotificationMethodType <that are not> types 

cevap

14

tiplerinin listesini asla değiştirirse, bunu yapabilirsiniz:

NotificationMethodType allTypes = NotificationMethodType.Email | 
    NotificationMethodType.Fax | 
    NotificationMethodType.Sms; 

NotificationMethodType notAssigned = allTypes & ~types; 

~ tüm bitleri ters yüz edilerek, ters bir değer oluşturur.

enum iki yeni isimler dahil etmek olurdu, en azından enum Yerel "allTypes" tanımı tutmak için böyle çeteleler tanımlamak için tipik bir yol:

[Flags] 
public enum NotificationMethodType { 
    None = 0, 
    Email = 1, 
    Fax = 2, 
    Sms = 4, 
    All = Email | Fax | Sms 
} 

Not: Gidersen enum All değer katmanın yolu, types boş olsaydı, bir enum almak değildir unutmayın o olur, bunun yerine "All" olarak "E-posta, faks, Sms" olarak baskı.

el allTypes listesini korumak istemiyorsanız, sen Enum.GetValues yöntemini kullanarak bunu yapabilirsiniz:

NotificationMethodType allTypes = 0; 
foreach (NotificationMethodType type in Enum.GetValues(typeof(NotificationMethodType))) 
    allTypes |= type; 

veya LINQ ile aynı yapabilirsiniz:

NotificationMethodType allTypes = 
    Enum.GetValues(typeof(NotificationMethodType)) 
    .Cast<NotificationMethodType>() 
    .Aggregate ((current, value) => current | value); 

Bu, allType değerini, enum'un tüm bireysel değerlerini birlikte OR'ing yaparak oluşturur. Basit bir XOR hile olacaktır

3

...

NotificationMethodType all = (NotificationMethodType.Email | NotificationMethodType.Fax | NotificationMethodType.Sms); 
    NotificationMethodType used = (NotificationMethodType.Email | NotificationMethodType.Fax); 
    NotificationMethodType unused = (all^used); 

, bu biraz daha temiz hale (besbelli 7'ye set değeri) doğrudan numaralandırma tanımına Tüm değer katmak. Bu şekilde, daha sonra cevap bu kodu

+0

FWIW, XOR (^ operatörler) kırma ve Lasse adlı 'değil de' olmadan enum şeyler ekleyebilir matematiksel olarak aynı şeydir. –

0
var notAssigned = Enum.GetValues(typeof(NotificationMethodType)) 
         .Cast<NotificationMethodType>() 
         .Where(x => !types.HasFlag(x)) 
         .Aggregate((a, x) => a | x); 
+0

, bitez operatörlerini kullanan 2 cevaptan herhangi birinden daha az etkilidir. –

+0

@Robert: Daha az verimli olduğunu inkar edemiyorum, ancak uygunluğu gerçekten OP'nin neye ihtiyacı olduğuna bağlı. Kendi cevabınız ana enum ile eşzamanlı olarak tutulacak ayrı bir "all" değerine ihtiyaç duyar - bu enum değiştiği takdirde bir bakım kabusu! (Ve bu daha fazla bir dezavantajdır, imo, muhtemelen çoğu durumda * asla * fark edilecektir sözde bir verimlilik problemi. Açıkçası ben daha az özgür-ve-ben sizin oy verme ile kolay.) – LukeH

+0

enumun bir parçası olarak tanımlanmalıdır –