Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么有Enumerator结构和EnumeratorImpl类?_C#_Roslyn - Fatal编程技术网

C# 为什么有Enumerator结构和EnumeratorImpl类?

C# 为什么有Enumerator结构和EnumeratorImpl类?,c#,roslyn,C#,Roslyn,我正在使用反射镜查看,我注意到ChildSyntaxList结构具有以下内容: public struct ChildSyntaxList : IEnumerable<SyntaxNodeOrToken> { private readonly SyntaxNode node; private readonly int count; public Enumerator GetEnumerator() { return node == n

我正在使用反射镜查看,我注意到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();
        }
    }
}
公共结构ChildSyntaxList:IEnumerable { 私有只读SyntaxNode; 私有只读整数计数; 公共枚举器GetEnumerator() { 返回节点==null?新枚举数():新枚举数(节点,计数); } IEnumerator IEnumerable.GetEnumerator() { 返回节点==null ?SpecializedCollections.EmptyEnumerator() :新枚举数mpl(节点,计数); } IEnumerator IEnumerable.GetEnumerator() { 返回节点==null ?SpecializedCollections.EmptyEnumerator() :新枚举数mpl(节点,计数); } 公共结构枚举器 { 内部枚举器(SyntaxNode节点,int计数) { /*逻辑*/ } 公共SyntaxNodeOrToken当前{get{/*logic*/} 公共图书馆 { /*逻辑*/ } 公共无效重置() { /*逻辑*/ } } 私有类枚举器mpl:IEnumerator { 私人统计员; 内部枚举数MPL(SyntaxNode节点,int计数) { 枚举数=新枚举数(节点,计数); } 公共SyntaxNodeOrToken当前{get{return enumerator.Current;} 对象IEnumerator.Current{get{return enumerator.Current;} 公共空间处置() { } 公共图书馆 { 返回枚举数.MoveNext(); } 公共无效重置() { 枚举数。重置(); } } } 也就是说,有一个
GetEnumerator
方法返回一个结构

看起来是这样的

  • 如前所述,使用结构会获得与BCL结构类似的性能增益,并且
  • 结构没有实现,因此不必担心这样做可能导致的错误
  • 但是,与BCL类不同,它有一个嵌套的
    EnumeratorImpl
    类。这样做的目的是为了

  • 避免使用一次性结构,以及
  • 避免显式实现的
    IEnumerable.GetEnumerator
    IEnumerable.GetEnumerator
    方法中的装箱
  • 还有其他原因吗

    还有其他原因吗

    我想不起来了。您似乎已经准确地描述了这个序列模式的奇怪实现的目的


    我得赶紧补充一句:Roslyn是一个不同寻常的.NET应用程序,它的复杂性、性能要求以及它生成的对象数量都是如此。一个编译器在用户输入时分析包含数千个文件、数百万行和数千万个字符的程序,它必须做一些非常不寻常的事情,以确保它不会淹没垃圾收集器。因此,Roslyn使用池策略、可变值类型和其他非主流做法来帮助实现这些性能目标。我不建议承担与这些实践相关的费用和困难,除非您有经验证据表明这些实践可以缓解严重的性能问题。仅仅因为这段代码是由C#编译器团队编写的,并不意味着这是编写主流业务对象的黄金标准

    我同意您不会做这些优化,除非它们是必需的(如经验证据所示),因为它们的开发和维护成本。但是如果他们是免费的呢?如果某个代码生成器或编译器可以为您执行这些优化,这样您就不必键入或读取它们了,该怎么办?是否有证据表明Roslyn编译器是使用这样的代码生成器或重写器编写的,甚至Roslyn编译器本身也在进行这些优化?两者都有可能。。。