c# - 逆变接口(interface)实现顺序

标签 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()); // ?
    }
}

如何处理至少两个调用?

通过一些测试,我可以说第一个调用 (DoubleVisitor1) 写入“Int”,第二个调用写入“Double”,但我在网上找不到任何东西,除了 Eric Lippert 的一篇戏弄相同内容的帖子如果在 IEnumerable 中使用,情况会导致。最好从语言或 Microsoft 文档中获得引用。

最佳答案

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

  • 恰好声明订单今天
  • 但谨慎的做法是将此视为未定义的行为,而不是依赖它
  • 特别注意,C# 可以有未定义的声明顺序无论如何(参见:partial class)

关于c# - 逆变接口(interface)实现顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58500453/

相关文章:

inheritance - 接口(interface)与抽象和继承

c# - Azure 数据库水平分片是 Multi-Tenancy C# asp.net 应用程序的最佳解决方案

c# - PdfContentByte.SetFontAndSize() 抛出 "Object reference not set to instance of object"

android - JUnit 断言 Activity 是接口(interface)的实现

C#:如何实现 IOrderedEnumerable<T>

php - 使用 count() 计算实现 ArrayAccess 的对象的元素?

c# - 如何将海量数据离线存储,然后批量更新到SQLite数据库中?

c# - 这两种事务处理方式有什么区别

c# - GenericType <T> 传递给 WEB-API

go - 将结构转换为 slice 结构