让我们采取以下代码:
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?}
是否有正确的方法可以检测到可以为空的nullable为nullable,或者我需要手动查看其中一个类型infos是否为空,而其他类型信息是否可以为空?
不同行为的示例:
让我们采取结构:
public struct N<T> where T : struct
{
public static explicit operator T(N<T> value)
{
return default(T);
}
}
在
之前使用它就像可以为空 N<int> e;
int d = (int) e;
@Kirk Woll是正确的,GetConversion
和GetTypeInfo
是相同的,但GetSymbolInfo
会返回public static explicit operator T(N<T> value)
方法。
Nullable具有完全相同的方法,但不会返回。
没有调用操作符emmited compiller会生成对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
答案 0 :(得分:3)
在施法操作中:
int b = (int)a;
你有演员表达:
(int)a
CastExpressionSyntax
具有Expression
属性(代表a
)和Type
属性(代表int
)。因此,在我使用VisitCastExpression
执行此操作时,我查询两个值以确定转换的from和to:
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
是表达式经过任何隐式转换后的类型。在您的示例中,convertedType
和originalType
都应为int?
。
因此,我并不完全确定你希望Roslyn以何种方式表现出不同的行为,但在我看来,我的行为与我期望的完全一样。
至于为什么没有返回符号信息,我的猜测是编译器实际上没有发出调用该运算符重载的代码并隐式处理这样的转换。因此,如果提供该符号,那将是不正确的。