c# - 为什么在将可空类型转换为 Roslyn 中的基类时没有转换?

标签 c# roslyn

让我们看下面的代码:

int? a = null;
int b = (int)a;

并提取CastExpressionSyntax对于 (int)a表达。

没有转换:

semanticModel.GetConversion(node) == {Identity}

没有符号(我希望是 Nullable<T> implicit operator T )

semanticModel.GetSymbolInfo(node).Method == null

类型信息的两个值相同

semanticModel.GetTypeInfo(node) == {Type = Int32, ConvertedType = Int32}
semanticModel.GetTypeInfo(node.Expression) == {Type = Int32?, ConvertedType = Int32?}

是否有正确的方法来检测可空到不可空的强制转换,或者我需要手动查看类型信息中的一个是否可以为空而另一个不是?

不同行为的示例:

让我们来看看结构:

 public struct N<T> where T : struct
 {
     public static explicit operator T(N<T> value)
     {
        return default(T);
     }
 }

并且像之前的nullable一样使用它

 N<int> e;
 int d = (int) e;

@Kirk Woll 是对的 GetConversionGetTypeInfo会是一样的,但是 GetSymbolInfo会返回 public static explicit operator T(N<T> value)方法。

Nullable 具有完全相同的方法,但不返回。

没有调用运算符 emmited 编译器生成对 Value 属性的直接调用。

IL_0001:  ldloca.s    00 // a
IL_0003:  initobj     System.Nullable<System.Int32>
IL_0009:  ldloca.s    00 // a
IL_000B:  call        System.Nullable<System.Int32>.get_Value
IL_0010:  stloc.1     // b

最佳答案

在强制转换操作中:

int b = (int)a;

你有转换表达式:

(int)a

CastExpressionSyntax 有一个Expression 属性(代表a)和Type 属性(代表整数)。因此,在我使用 VisitCastExpression 实现此方法时,我查询两个值以确定转换的起始和终止:

var typeInfo = model.GetTypeInfo(node.Expression);
var originalType = typeInfo.Type;
var convertedType = typeInfo.ConvertedType;
var destinationType = model.GetTypeInfo(node.Type).Type;

destinationType 始终是您要强制转换的目标(在您的情况下为 int)。 originalType 是表达式在进行任何隐式转换之前的类型。 convertedType 是表达式经过任何隐式转换后的类型。在您的示例中,convertedTypeoriginalType 都应为 int?

所以我不完全确定您希望 Roslyn 以何种方式表现不同,但在我看来,它的表现完全符合我的预期。

至于为什么没有返回符号信息,我的猜测是编译器实际上不会发出调用该运算符重载的代码并隐式处理此类转换。因此,如果它提供了该符号,那将是不正确的。

关于c# - 为什么在将可空类型转换为 Roslyn 中的基类时没有转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27230659/

相关文章:

c# - Entity Framework :- Error when Casting to derive class throw exception in Table per hierarchy query

c# - Func<T, bool> 和 Predicate<T> 编译后不是一回事吗?

visual-studio-2015 - 在哪里可以找到 VS 2015 的 Roslyn 项目模板?

c# - 如何找到变量声明未在 Roslyn 的类中使用?

c# - 从 HandleTypeDeclaration(...) 中的 SyntaxNodeAnalysisContext 获取封闭类型

c# - C# 中的字符串解析(对我来说)很困难(正则表达式?)

c# - 是否可以在派生类或任何其他类中调用抽象类的方法

c# - Silverlight 3/Prism - 将枚举值作为命令参数传递

c# - Roslyn - 抛出构建错误

.net - 在构建服务器上运行 Roslyn 代码分析器