Roslyn-创建一个SeparatedList<;T>;从产量';ed IEnumerable<;T
本文关键字:lt IEnumerable ed gt 创建 一个 SeparatedList Roslyn- | 更新日期: 2023-09-27 18:24:41
我正在尝试使用动态生成的IEnumerable
序列(由Enumerable.Select()
函数调用构建)来构建SeparatedList
。创建SeparatedList
的API函数采用两个参数:IEnumerable<T>
和IEnumerable<SyntaxToken>
。我提供了一个简单的函数Repeat
,它是一个无限序列生成器,在本例中,根据需要生成任意数量的逗号。
SeparatedList
函数似乎消耗了与第二个序列中的条目一样多的第一个序列(此处为参数类型),这让我很困惑。我是否误解了该功能的工作方式,是否有其他人这样做?感谢
Syntax.SeparatedList<ParameterSyntax>(
functionParameterTypes,Repeat(i=>Syntax.Token(SyntaxKind.CommaToken)))
(编辑:我应该补充一点,将functionParameterTypes
转换为List<>
,并传递另一个比functionParameterTypes
中的元素少一个令牌的List<>
确实有效,但我正在努力做到这一点,而不必提前显式构建列表。)
separators
参数的XML文档显示:
令牌的数量必须比节点的数量少一个。
你说得对,这不是该方法实际需要的:令牌的数量必须比节点的数量少一个,或者与令牌的数量相同。如果这是故意的,我不会感到惊讶,如果你试图处理刚刚编写的代码,像f(foo, bar, )
这样的代码是有意义的。
我认为在参数序列上调用ToList()
是最好的选择。您不必使用另一个List
作为分隔符,您可以使用Enumerable.Repeat()
作为分隔符。例如这样的例子(取自我写的一个图书馆,我在那里遇到了同样的问题):
public static SeparatedSyntaxList<T> ToSeparatedList<T>(
this IEnumerable<T> nodes, SyntaxKind separator = SyntaxKind.CommaToken)
where T : SyntaxNode
{
var nodesList = nodes == null ? new List<T>() : nodes.ToList();
return Syntax.SeparatedList(
nodesList,
Enumerable.Repeat(
Syntax.Token(separator), Math.Max(nodesList .Count - 1, 0)));
}
我也同样需要使用动态生成的参数列表创建SeparatedList
。我的解决方案是使用SelectMany()
和Take()
在参数中添加分隔符(即"逗号"),然后删除最后一个尾随逗号。
SyntaxFactory.SeparatedList<ParameterSyntax>(
functionParameterTypes
.SelectMany(param =>
new SyntaxNodeOrToken[]
{
param,
SyntaxFactory.Token(SyntaxKind.CommaToken)
})
.Take(functionParameterTypes.Count() * 2 - 1)
);