switch ステートメントのケース数をカウントする C# メソッドが必要です。( と呼びましょうCaseCounter
)。たとえば、この列挙型と次の 2 つのメソッドがあるとします。
enum Painter
{
Rubens,
Rembrandt,
Vermeer,
Picasso,
Kandinsky
}
int GetYearOfBirth(Painter painter)
{
switch(painter)
{
case Painter.Kandinsky:
return 1866;
case Painter.Picasso:
return 1881;
case Painter.Rembrandt:
return 1606;
case Painter.Rubens:
return 1577;
case Painter.Vermeer:
return 1632;
default:
return 0;
}
}
bool IsModern(Painter painter)
{
switch (painter)
{
case Painter.Kandinsky:
case Painter.Picasso:
return true;
default:
return false;
}
}
ここで、次の等式が成り立つはずです。
CaseCounter("GetYearOfBirth") == 5
CaseCounter("IsModern") == 2
(カウントにデフォルトのケースを含めるかどうかは重要ではありません。また、パラメータ toCaseCounter
は文字列である必要はありません。メソッドを表すために何らかの形で使用できる型であれば何でもかまいません。)
では、どのように実装しCaseCounter
ますか? それは可能ですか?
--- 補遺 (編集) ---
なぜ私がこの質問をしたのか疑問に思っている方のために、ここに少し背景情報を示します。
列挙型をオンにする多くのメソッドを含むコード ベースを維持しています。メソッドはさまざまなクラスに分散しています。これにより、列挙型が拡張された場合 (たとえば、新しい を追加した場合Painter
) は困難になります。メンテナンスを少し簡単にするために、次の形式の単体テストをいくつか作成しました。
// If this test fails please check that the following methods are still OK:
// MyClass.GetYearOfBirth, MyOtherClass.IsModernAllCases .
// (There is no guarantee that the above list is up-to-date or complete.)
[Test]
public void PainterCountTest()
{
int numberOfMembers = Enum.GetValues(typeof(NotificationID)).Length;
Assert.AreEqual(5, numberOfMembers);
}
(この例では、 は列挙型の 5 つの可能な値すべてを明示的に参照IsModernAllCases
する単なるバリエーションです。)IsModern
Painter
このテストは何もないよりはましですが、扱いにくいです。次のように書くことができれば、少しぎこちなくなります。
[Test]
public void PainterCountTest()
{
int numberOfMembers = Enum.GetValues(typeof(NotificationID)).Length;
int numberOfCases_getYearOfBirth = CaseCounter("MyClass.GetYearOfBirth");
Assert.AreEqual(numberOfCases_getYearOfBirth, numberOfMembers);
int numberOfCases_modern = CaseCounter("MyOtherClass.IsModernAllCases");
Assert.AreEqual(numberOfCases_modern, numberOfMembers);
}
このシナリオでは、少なくとも、列挙型を拡張するときに単体テストを変更する必要はありません。