我的問題的關鍵部分是跳過。我打算使用大約20個元素的枚舉類型。我想遍歷這個集合,但每次都需要跳過一個或兩個元素。事先知道要跳過什麼。一個可比較的例子是枚舉類型,它由字母表中的所有字母組成,迭代時,我想跳過所有的元音。如何遍歷枚舉類型,同時跳過一些值?
我應該如何以優雅/有效的方式編碼迭代?我應該製作一組由元音組成的獨立元素嗎?我沒有代碼可以顯示,因爲我只是在想這個問題。
我的問題的關鍵部分是跳過。我打算使用大約20個元素的枚舉類型。我想遍歷這個集合,但每次都需要跳過一個或兩個元素。事先知道要跳過什麼。一個可比較的例子是枚舉類型,它由字母表中的所有字母組成,迭代時,我想跳過所有的元音。如何遍歷枚舉類型,同時跳過一些值?
我應該如何以優雅/有效的方式編碼迭代?我應該製作一組由元音組成的獨立元素嗎?我沒有代碼可以顯示,因爲我只是在想這個問題。
var query = Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.Except(new MyEnum[] { MyEnum.A, MyEnum.E });
foreach (MyEnum item in query) {
...
}
你需要爲了得到LINQ的魔法施放。 Except
一個人不會這樣做。
UPDATE:
我有另一個想法。您可以使用FlagsAttribute
定義枚舉,並將常規值定義爲2的冪,這是使用按位左移運算符<<
最容易實現的。從C#7.0開始,您還可以使用像0b_0000_0000_0010_0000
這樣的二進制文字。然後可以將現有值組合以形成新的值。現在
[Flags]
enum MyEnum
{
None = 0,
A = 1 << 0,
B = 1 << 1,
C = 1 << 2,
D = 1 << 3,
E = 1 << 4,
...
X = 1 << 23,
Y = 1 << 24,
Z = 1 << 25,
Vowels = A | E | I | O | U
}
,你可以制定這樣的
IEnumerable<MyEnum> query = Enum.GetValues(typeof(MyEnum))
.Cast<MyEnum>()
.Where(x => (x & MyEnum.Vowels) == MyEnum.None);
foreach (MyEnum item in query) {
...
}
在第一解決方案的優點是查詢,你可以用一個位與操作進行測試。
您最多可以定義32個冪。如果您需要更多,則可以將枚舉的基本類型定義爲long
並使用最多64個標誌值(加上現有標誌值的組合)。
[Flags]
enum MyEnum : long
{
...
}
我會做一個單獨的一組元素組成的元音,然後使用LINQ兩組之間的設置差異。
int[] vowels = {Letters.A, Letters.E, Letters.I, Letters.O, Letters.U};
IEnumerable<int> consonant = Enum.GetValues(typeof(Letters)).Except(vowels);
foreach (int consonant in consonants)
{
// Do something with each consonant
}
我可能只是使用LINQ - 使用Enum.GetValues
(或使用Unconstrained Melody - 一個類型安全的泛型枚舉/委託庫我寫的),讓所有的值,則表示該值保持/通過跳躍Where
子句。
如果你只是跳過特定的值,那麼HashSet
或類似的東西可能是有用的(如果你只跳過一個值,那就不值得) - 如果你基於條件跳過,那麼滿需要謂詞。
例如:
public static IEnumerable<T> AllBut(T skipped) where T : struct
{
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
return AllBut<T>(t => !comparer.Equals(skipped, t));
}
public static IEnumerable<T> AllBut(Func<T, bool> skipPredicate) where T : struct
{
IEqualityComparer<T> comparer = EqualityComparer<T>.Default;
return Enum.GetValues(typeof(T))
.Cast<T>()
.Where(t => skipPredicate(t));
}
這可能是最完整的答案。最簡單的做法是指定各種你想跳過的枚舉集合,這樣你可以保存這些跳過集合,並且可以通過你想要的任何標準傳入Except。 – SPFiredrake 2012-03-12 17:42:39
是的,你也可以保留各種查詢。 – 2012-03-12 17:46:03
我添加了另一個解決方案,僅使用按位AND進行測試。它不需要任何數組或HashSets作爲例外值。請參閱我的更新。 – 2012-03-12 22:56:51