我想要一个C#方法来计算交换机语句中的个案数。 (我们称之为CaseCounter
)。例如,假设你有这个枚举和这两种方法:
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
(在计数中是否包含默认情况并不重要。此外,CaseCounter
的参数不需要是字符串;任何可以某种方式用于表示方法的类型会做的。)
那么,您将如何实施CaseCounter
?它甚至可能吗?
--- ADDENDUM(编辑)---
如果你想知道为什么我问这个问题,这里有一些背景信息。
我正在维护一个代码库,其中包含很多打开枚举的方法。这些方法分布在各个类别中;这会在枚举枚举时使生活变得困难(例如,当您添加新的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);
}
(在此示例中,IsModernAllCases
只是IsModern
的变体,它明确引用Painter
枚举的所有5个可能值。)
这个测试总比没有好,但它很笨拙。如果你能写出这样的东西,那就不那么笨拙了:
[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);
}
在这种情况下,至少在扩展枚举时不必修改单元测试。
答案 0 :(得分:5)
应该可以使用the Roslyn CTP - Microsoft的编译器即服务预发布产品。它具有API,可让您检查C#代码并将其表示为指令树。不幸的是,它是一个CTP,对你来说可能是也可能不是问题 - 只要记住它是预发布软件,如果你试图使用它。
如果您不能使用Roslyn,我认为唯一的方法是检查生成的IL。至少可以说是一项艰巨的任务。我没有任何示例代码,但是如果你想尝试一下 - 我会先看一下Cecil Mono项目,它有一些用于检查IL的API。
您也可以MethodInfo.GetMethodBody
获取原始IL字节,然后自己解析这些字节,但确实需要做一些工作。
答案 1 :(得分:4)
这不能通过Reflection完成,但可以通过Roslyn CTP完成。 Roslyn提供了分析源代码本身所需的工具,并确定了有关它的信息。您可以在此代码中遍历树以查找包含switch语句的方法,并计算单个案例。
答案 2 :(得分:3)
在不知道你为什么要这样做的情况下,很难知道这对你来说是否是一种可接受的方法。
由于这些C#文件基本上只是计算机上的文本文件,因此您可以创建一个循环遍历所有文件的单独应用程序。它需要识别方法,计算case
个单词(不是注释)的出现次数,并报告结果。
现在,如果您需要在运行时在应用程序中运行此功能,则此方法将无效。
答案 3 :(得分:0)
在视觉工作室中根据您的案例词进行搜索搜索,这足以让您进行重构