在 roslyn 分析期间从 switch 语句中的可空枚举类型获取实际枚举类型

Get the actual enum type from a nullable enum type in a switch statement during roslyn analyis

我想分析一个 switch 语句,它使用“可空枚举”来决定。 我有以下 class 我想分析:

namespace Common.Model.Schema
{
    public enum ModuleType
    {
        Case1,
        Case2,
        Case3
    }   
}

namespace Analyzer.Test
{
    using Common.Model.Schema;

    public class Test
    {
        private static void GetSelectedAblageOrdner()
        {
            ModuleType? moduleType = null;
            switch (moduleType)
            {
                case ModuleType.Case1:
                {
                    break;
                }
            }
        }
    }
}

当开关的输入可为空时,我可以使用以下代码,并且我有正确的类型来进行分析。

TypeInfo typeInfo = context.SemanticModel.GetTypeInfo(expression);
ITypeSymbol expressionType = typeInfo.ConvertedType;
if (!(expressionType is INamedTypeSymbol namedType))
{
    return;
}

switch (namedType.EnumUnderlyingType.Name)
{
      // do stuff
}

但是对于可为 null 的枚举,convertedType 是 Nullable<ModuleType>(或者换句话说 ModuleType?)。这使得 属性 EnumUnderlyingType 等为 NULL。我需要实际枚举以便继续。

如何到达 ModuleType,以便我可以继续使用我的默认算法来处理不可为 null 的枚举?

Nullable<> 只是一个泛型。检查它是否是通用的并获取它的参数。

if (typeof(Nullable<>) == typeInfo.ConvertedType.GetGenericTypeDefinition())
{
   var actualType = typeInfo.ConvertedType.GetGenericArguments()[0];
}

Quercus 为我指明了正确的方向。这是我的解决方案:

if (namedType.IsGenericType)
{
    INamedTypeSymbol typeSymbol = namedType.TypeArguments.FirstOrDefault() as INamedTypeSymbol;
    if (typeSymbol == null)
    {
        return;
    }

    expressionType = typeSymbol;
    namedType = typeSymbol;
}