我正在尝试从与 Roslyn 的SwitchStatement
中收集开关部分标签常量。但是,虽然我可以在语法可视化工具中看到CaseSwitchLabelSyntax
具有具有相应常量的Value
属性,并且声明的符号 (SourceLabelSymbol
( 具有SwitchCaseLabelConstant
属性,但我似乎无法从代码中获取该信息。
// SwitchStatementSyntax node;
// SemanticModel model;
foreach (var section in node.Sections) {
foreach (var label in section.Labels) {
var labelSymbol = model.GetDeclaredSymbol(label);
// Here I'm stuck
}
}
我可能会看看SwitchLabelSyntax
是CaseSwitchLabelSyntax
还是DefaultSwitchLabelSyntax
,并相应地投射。 SourceLabelSymbol
实际上是内部的,所以我无法访问它的属性。 model.GetConstantValue(label)
返回null
.
但鉴于 Roslyn 总是分发界面,我相信这是有原因的,疯狂地四处投掷对我来说有点笨拙。有没有更好的选择?
注意:我这样做是为了将 C# 语法翻译成另一种语言。从技术上讲,首先进入单独的 AST,然后再次转换为文本。上面的代码来自CSharpSyntaxWalker
,我可能只是将部分转换的switch
语句存储起来,继续访问它的后代并分段构建它。
但这意味着拥有更多的状态,在六个不同的位置构建语句,这导致难以阅读和遵循代码。如果可能的话,我宁愿在这里避免它。
最接近 API 的是semanticModel.GetConstantValue
方法,但您仍然需要像这样将 Value 节点传递给它:
section.Labels
.OfType<CaseSwitchLabelSyntax>()
.Select(l => semanticModel.GetConstantValue(l.Value))
.ToArray()
如您所见,无论如何都需要过滤掉CaseSwitchLabelSyntax
。