在C#中,如何评估类的任何成员是否包含switch case或else构造?

在C#中,如何评估类的任何成员是否包含switch case或else构造?,c#,reflection,system.reflection,methodbase,C#,Reflection,System.reflection,Methodbase,在C#中,如何评估类的任何成员是否包含switch case或else构造?我想在单元测试中检查类是否使用switch…case或链接if…else编写 我知道如何使用反射获取类的成员,但在互联网上找不到如何获取实际代码的示例。从这篇文章中,我发现您可以使用MethodBase.GetMethodBody()。这对于返回一个用于获取变量的参数似乎很好,但无法找到如何获取switch…case或if…else是否存在的信息 有可用的解决方案吗?您不能使用反射。是的,你可以得到IL字节数组的方法,但

在C#中,如何评估类的任何成员是否包含switch case或else构造?我想在单元测试中检查类是否使用
switch…case
或链接
if…else
编写

我知道如何使用反射获取类的成员,但在互联网上找不到如何获取实际代码的示例。从这篇文章中,我发现您可以使用
MethodBase.GetMethodBody()
。这对于返回一个用于获取变量的参数似乎很好,但无法找到如何获取
switch…case
if…else
是否存在的信息


有可用的解决方案吗?

您不能使用反射。是的,你可以得到IL字节数组的方法,但它对你的要求是无用的

实现你所需要的最好的方法就是使用Roslyn,那就再简单不过了

bool ContainsIfElseOrSwitchTest()
{
    var classToTest = // you can get it from your VS solution 
                      // or by reading the .cs file from disk
    // for example
    classToTest = CSharpSyntaxTree.ParseText(File.OpenRead(pathToFile));

    return classToTest.GetRoot().DescendantNodes().
              Any(node => node is SwitchStatementSyntax || node is IfStatementSyntax);
}
根据评论更新答案

另一个选项是使用
Mono.Cecil
直接获取IL指令,而不使用字节数组。但您必须知道,您只能知道指令是否包含条件,而无法知道它是
if else
还是
开关


当然,另一个选择是自己解析文本并找到想要的内容。

您看到了吗?您是在寻找任何控制流还是仅仅是这两个结构?当它被编译成IL时,这些结构已经不存在了。所以,如果你只想针对那些构造,你将尝试从IL进行反向工程。我认为这是不可能的。编译器可能会将这些构造转换为不同的IL语句或相同的IL语句,这取决于几个方面。例如,如果你有pdb,我认为这是可能的,但不是一件小事。你可以深入研究它是如何对代码进行反向工程并提取方法的文本的。您正在谈论代码检查,最简单的方法是代码检查。另一种方法是编写一个VS/Roslyn加载项来解析AST,就像Resharper一样。@Dib如果你真的不在乎怎么做,只是得到结果,也许你真的自己解析它。因为
如果
else
switch
是c#字,您可以很容易地检查它是否存在于方法块中(但不是作为注释)。@Dib您无法从框中获取文本。只需解析它:\。如果你想通过IL翻译实现这一点,但你不能使用
Cecil
,请查看我的其他SO答案或如何实现这一点的示例,但我告诉你,这不是一种有趣的方式。嗯,如果IL流中有
0x45
操作码,并且它是用当前的C编译器编写的,那么可以安全地假设源代码有一个
开关,但是相反的情况并不成立,因为C也可以将
开关编译成一个相当于
if
-
else
的链,在一个
if
-
else
和另一个.NET语言编译器中,两个或多个
开关可能会再次执行非常不同的操作。@jonhana当然。我警告过他这一点,但他只是想知道是否使用了其中一个,这样无论它是
开关还是
如果…否则
或者甚至是
标志都无关紧要?expr:otherExpr
@DudiKeleti-我确实试着在你的链接中了解代码,你也有一个程序集,我下载了它,看看是否有帮助。看起来我没有太多的选择,因为我有一个回合的限制,所以我会尝试让我的头围绕你的例子,并使用它。干得好,顺便说一句!