我正在使用Reflector查看Roslyn September 2012 CTP,我注意到ChildSyntaxList结构具有以下内容:
public struct ChildSyntaxList : IEnumerable<SyntaxNodeOrToken>
{
private readonly SyntaxNode node;
private readonly int count;
public Enumerator GetEnumerator()
{
return node == null ? new Enumerator() : new Enumerator(node, count);
}
IEnumerator<SyntaxNodeOrToken> IEnumerable<SyntaxNodeOrToken>.GetEnumerator()
{
return node == null
? SpecializedCollections.EmptyEnumerator<SyntaxNodeOrToken>()
: new EnumeratorImpl(node, count);
}
IEnumerator IEnumerable.GetEnumerator()
{
return node == null
? SpecializedCollections.EmptyEnumerator<SyntaxNodeOrToken>()
: new EnumeratorImpl(node, count);
}
public struct Enumerator
{
internal Enumerator(SyntaxNode node, int count)
{
/* logic */
}
public SyntaxNodeOrToken Current { get { /* logic */ } }
public bool MoveNext()
{
/* logic */
}
public void Reset()
{
/* logic */
}
}
private class EnumeratorImpl : IEnumerator<SyntaxNodeOrToken>
{
private Enumerator enumerator;
internal EnumeratorImpl(SyntaxNode node, int count)
{
enumerator = new Enumerator(node, count);
}
public SyntaxNodeOrToken Current { get { return enumerator.Current; } }
object IEnumerator.Current { get { return enumerator.Current; } }
public void Dispose()
{
}
public bool MoveNext()
{
return enumerator.MoveNext();
}
public void Reset()
{
enumerator.Reset();
}
}
}
也就是说,有一个返回结构的GetEnumerator
方法。
看起来像那样
List<T>.Enumerator
结构的性能增益,如in this answer所述,IDisposable
,因此不必担心这样做可能导致的错误,as noted on Eric Lippert's blog。但是,与BCL List<T>
类不同,有一个嵌套的EnumeratorImpl
类。是的目的是
IEnumerable<SyntaxNodeOrToken>.GetEnumerator
和IEnumerable.GetEnumerator
方法中装箱?还有其他原因吗?
答案 0 :(得分:19)
还有其他原因吗?
没有想到的。您似乎已经准确地描述了序列模式这种相当奇怪的实现的目的。
我必须补充一点:Roslyn是一个不寻常的.NET应用程序,其复杂性,性能要求以及它生成的对象数量。在用户输入时,用数千个文件,数百万行和数千万个字符分析程序的编译器必须做一些非常不寻常的事情,以确保它不会淹没垃圾收集器。因此,Roslyn使用汇集策略,使用可变值类型以及其他非主流实践来帮助实现这些性能目标。我不建议承担与这些做法相关的费用和难度,除非您有经验证据确定这些做法可以缓解的严重性能问题。仅仅因为此代码是由C#编译器团队编写的,并不意味着这是您应该如何编写主流业务对象的黄金标准。