Feedback

C# - Enum-Extension - Flag in einem Bitfeld gesetzt?

Veröffentlicht von am 30.11.2009
(2 Bewertungen)
Wer hat nicht schon oft mit Code ähnlich dem Folgenden überprüfen müssen, ob in einem Bitfeld ein bestimmtes Flag gesetzt ist:

if ((FlagA & bitfeld) == FlagA)) { ... }

Die folgenden Extensions erweitern jedes Enum mit der Extension-Methode "Contains". Damit lässt sich nun obiger Code einfacher schreiben:

if (bitfeld.Contains(FlagA)) { ... }

Die generische Variante dieser Methode überprüft zudem, ob das Enum mit dem "Flags"-Attribut gekennzeichnet wurde. :

if (bitfeld.Contains<FlaggedEnum>(FlagA)) { ... }
/// <summary>
/// Überprüft, ob in dem Bitfeld en1 das Bitfeld en2 enthalten ist.
/// </summary>
/// <param name="en1">Bitfeld 1</param>
/// <param name="en2">Bitfeld 2</param>
/// <returns><c>True</c>, wenn en2 in en1 enthalten ist, sonst <c>False</c>.</returns>
/// <remarks>Bei dieser überlagerten Version der Methode wird nicht überprüft, ob die beiden Bitfelder gleichen Typs sind.
/// <para>Verwenden Sie daher bitte die generische Version dieser Methode, wenn Sie sicherstellen müssen, dass beide Bitfelder gleichen Typs sind.</para></remarks>
public static bool Contains(this Enum en1, Enum en2) {
	return ((Convert.ToInt32(en1) & Convert.ToInt32(en2)) == Convert.ToInt32(en2));
}

/// <summary>
/// Überprüft, ob in dem Bitfeld en1 das Bitfeld en2 enthalten ist.
/// </summary>
/// <typeparam name="TFlaggedEnum">Parameter, der den Typ der Bitfelder angibt.</typeparam>
/// <param name="en1">Bitfeld 1</param>
/// <param name="en2">Bitfeld 2</param>
/// <returns><c>True</c>, wenn en2 in en1 enthalten ist, sonst <c>False</c>.</returns>
public static bool Contains<TFlaggedEnum>(this Enum en1, Enum en2) {
	if (!(Attribute.IsDefined(typeof(TFlaggedEnum), typeof(FlagsAttribute)))) return false;
	if ((en1.GetType().ToString() != en2.GetType().ToString())) return false;
	if ((en1.GetType().ToString() != typeof(TFlaggedEnum).ToString())) return false;
	return ((Convert.ToInt32(en1) & Convert.ToInt32(en2)) == Convert.ToInt32(en2));
}
Abgelegt unter Enum, Extension, Generics, Bitfeld.

1 Kommentare zum Snippet

T.Östreich schrieb am 08.12.2009:
Verbesserungsvorschlag:

public static bool IsSet<TEnum>(this TEnum value, TEnum flag) where TEnum : struct
{
if (!typeof(TEnum).IsEnum)
throw new ArgumentException("TEnum must be an enumerated type");

long valueBase = Convert.ToInt64(value);
long flagBase = Convert.ToInt64(flag);
return (valueBase & flagBase) == flagBase;
}


Test:

/// <summary>
///Ein Test für "IsSet"
///</summary>
public void IsSetTestHelper<TEnum>(TEnum v, TEnum flag, bool expected)
where TEnum : struct
{
bool actual = v.IsSet(flag);
Assert.AreEqual(expected, actual);
}

[TestMethod()]
public void IsSetTest()
{
Test t1 = Test.blue;
Test t2 = Test.green;
Test t3 = Test.blue | Test.red;
IsSetTestHelper<Test>(t1, Test.blue, true);
IsSetTestHelper<Test>(t2, Test.green, true);
IsSetTestHelper<Test>(t3, Test.red, true);
IsSetTestHelper<Test>(t3, Test.red | Test.green, false);
IsSetTestHelper<Test>(t3, Test.blue | Test.red, true);
}

[Flags]
enum Test
{
red = 1,
green = 2,
blue= 4
}
 

Logge dich ein, um hier zu kommentieren!