【问题标题】:Why there is no conversion when casting nullable type to it's base class in Roslyn?为什么在 Roslyn 中将可空类型转换为其基类时没有转换?
【发布时间】:2014-12-01 14:35:02
【问题描述】:

让我们使用以下代码:

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&lt;T&gt; 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

【问题讨论】:

  • nodenode.Expression 的类型信息不给你答案吗?
  • @KirkWoll,它确实,有点,但通常转换是存在的,所以我想知道这个案例有什么特别之处

标签: c# roslyn


【解决方案1】:

在强制转换操作中:

int b = (int)a;

你有演员表:

(int)a

CastExpressionSyntax 有一个Expression 属性(代表a)和Type 属性(代表int)。因此,在我使用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 以何种方式表现不同,但在我看来,它的表现完全符合我的预期。

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

【讨论】:

  • 你是对的,请添加你的评论来回答自己
猜你喜欢
  • 1970-01-01
  • 2019-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-07
  • 2012-04-21
相关资源
最近更新 更多