有没有办法声明一个在.Net中实现多个接口的变量?

Bry*_*son 18 .net interface

此Java问题类似.我想指定一个变量实现多个接口.例如

private {IFirstInterface, ISecondInterface} _foo;

public void SetFoo({IFirstInterface, ISecondInterface} value)
{
    _foo = value;
}
Run Code Online (Sandbox Code Playgroud)

要求:

  • 我无法为大多数传入Foo的类型添加接口.所以我无法创建继承自IFirstInterface和ISecondInterface的第三个接口.
  • 如果可能的话,我想避免使包含类变得通用,因为Foo的类型与类没有太大关系,并且用户在编译时不太可能知道它.
  • 我需要在以后使用foo来访问两个接口中的方法.
  • 我想以编译器安全的方式执行此操作,即在尝试使用它之前不尝试强制转换为接口.如果foo没有实现两个接口,相当多的功能将无法正常工作.

这可能吗?

编辑:出于各种原因,我想要这几次.在这个例子中,因为我正在将一组属性从ObservableCollections更改为ReadOnlyObservableCollections.我有一个帮助器类,它创建从源ObservableCollection到另一个Collection的投影.由于ReadOnlyObservableCollection不从ObservableCollection继承而且我只需要IList和INotifyCollectionChanged中的操作,我希望将我的源集合存储为这两个接口的组合,而不是需要ObservableCollection.

Dan*_*Tao 17

如果你想限制你的方法SetFoo采取只实现这两个接口的参数,那么你运气:

public void SetFoo<T>(T value) where T : IFirstInterface, ISecondInterface
{
    _foo = value;
}
Run Code Online (Sandbox Code Playgroud)

从这一点开始,只要您想要将您的_foo成员作为这两个接口之一访问,您就必须分别通过强制转换来访问它:(IFirstInterface)_foo或者(ISecondInterface)_foo.

你确实说过你想避免使用强制转换来实现编译时的安全性; 但我认为,如果你找到一种方法来确保_foo使用SetFoo上面的方法进行初始化,你可以安心地投出你想要的一切.


我才意识到下面介绍一些你在你的问题特别声明没有想做的事情.所以,我说,顺其自然.

另一个想法是,因为看起来这个_foo对象是一个类成员(我将这个假设基于_变量名),你可以用这种方式定义你的类:

class YourClassThatHasAFoo<T> where T : IFirstInterface, ISecondInterface {
    private T _foo;

    public void SetFoo(T value) {
        _foo = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

这实际上是否有意义取决于您的具体情况.你肯定要考虑它,因为有这种约束的类有时会导致你可能没想到的问题(比如SetFoo现在必须采用类型的参数T,而不仅仅是实现你的两个接口的任何类) .


Ada*_*son 6

不,没有办法以声明方式确保特定实例实现多个接口.

使用泛型可能有一种选择,尽管这实际上只适用于函数而不是属性.

public void Foo<T>(T arg)
    where T : IFirstInterface
    where T : ISecondInterface
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用类型推断,您应该能够像这样调用它:

ConcreteType bar = new ConcreteType(); // this implements both

Foo(bar);
Run Code Online (Sandbox Code Playgroud)