协方差接口的实现顺序

mar*_*co6 3 c# interface

采取这段代码:

using System;

public class Program
{
    interface IVisitable<T> { 
        void Accept(object o);
    }

    interface IVisitor<in T> {
        void Visit(T t);
    }

    class IntAndDoubleVisitable: IVisitable<int>, IVisitable<double>
    {
        public void Accept(object o) {
            if (o is IVisitor<IntAndDoubleVisitable>) {
                ((IVisitor<IntAndDoubleVisitable>)o).Visit(this);
            }
        }
    }

    class SingleVisitor<T>: IVisitor<T> {
        public void Visit(T visitor) {
            Console.WriteLine(typeof(T).FullName);
        }
    }

    class DoubleVisitor1: IVisitor<IVisitable<int>>, IVisitor<IVisitable<double>> {
        void IVisitor<IVisitable<int>>.Visit(IVisitable<int> t) {
            Console.WriteLine("Int");
        }

        void IVisitor<IVisitable<double>>.Visit(IVisitable<double> t) {
            Console.WriteLine("Double");
        }
    }

    class DoubleVisitor2: IVisitor<IVisitable<double>>, IVisitor<IVisitable<int>> {
        void IVisitor<IVisitable<int>>.Visit(IVisitable<int> t) {
            Console.WriteLine("Int");
        }

        void IVisitor<IVisitable<double>>.Visit(IVisitable<double> t) {
            Console.WriteLine("Double");
        }
    }

    public static void Main()
    {
        var visitable = new IntAndDoubleVisitable();
        visitable.Accept(new SingleVisitor<IVisitable<int>>()); // Fine
        visitable.Accept(new SingleVisitor<IVisitable<double>>()); // Fine
        visitable.Accept(new DoubleVisitor1()); // ?
        visitable.Accept(new DoubleVisitor2()); // ?
    }
}
Run Code Online (Sandbox Code Playgroud)

至少两个电话将如何处理?

通过很少的测试,我可以说第一个调用(DoubleVisitor1)编写为“ Int”,第二个调用编写为“ Double”,但是除了Eric Lippert的一则帖子嘲弄了相同情况会导致什么情况之外,我什么都找不到。在IEnumerable中使用。可以从该语言或Microsoft文档中获得参考。

Mar*_*ell 6

在IL级别,行为在ECMA 335(II.12.2)中定义为以引用IL声明表的声明顺序。但是,AFAIK C#不能正式保证将接口声明顺序从C#保留到IL中,因此:

  • 今天刚好申报单
  • 但请谨慎考虑,认为这是未定义的行为,而不要依赖它
  • 尤其需要注意的是C#可以有不确定的声明顺序反正(见partial class