在C#中使用多个接口键入多态值

Dar*_*rio 5 c# interface

是否有任何类型安全的,编译时检查的可能性来引用实现多个接口的值?

特定

interface A {
    void DoA();
}

interface B {
    void DoB();
}
Run Code Online (Sandbox Code Playgroud)

我可以编写代码实现对象A B,但不能同时使用.所以我想出了丑陋的包装:

class ABCollection {
    private class ABWrapper : A, B {
        private readonly A a;
        private readonly B b;

        public static ABWrapper Create<T>(T x) where T : A, B {
            return new ABWrapper { a = x, b = x };
        }

        public void DoA() {
            a.DoA();
        }

        public void DoB() {
            b.DoB();
        }
    }

    private List<ABWrapper> data = new List<ABWrapper>();

    public void Add<T>(T val) where T : A, B {
        data.Add(ABWrapper.Create(val));
    }
}
Run Code Online (Sandbox Code Playgroud)

是否有一种技巧可以更直观地编写此代码而不会丢失类型安全性(运行时转换等)?

例如

private List<A and B> ...
Run Code Online (Sandbox Code Playgroud)

编辑:这不是特别关注列表 - 我只是想给出一个存储这些值的问题的"完整"示例.我的问题是如何键入两个接口的组合(如A & BA and B).

另一个更有用的例子:List<IDrawable & IMovable>......

Eri*_*ert 7

您可以像C#中那样进行参数多态,但不能进行子类型多态.也就是说,您可以创建一个多态方法,如:

void Foo<T>(T t) where T : IFoo, IBar
{
  t.Foo();
  t.Bar();
}
Run Code Online (Sandbox Code Playgroud)

然后你必须传递一个在编译时类型已知的对象来实现IFoo和IBar.

但是没有办法说

void Foo(IFoo-and-IBar t) 
{
  t.Foo();
  t.Bar();
}
Run Code Online (Sandbox Code Playgroud)

然后传入一个既是IFoo又是IBar的值.整洁的功能,但不是我们支持的功能.