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

有没有办法声明一个在.Net中实现多个接口的变量?,.net,interface,.net,Interface,类似于。我想指定一个变量实现多个接口。比如说 private {IFirstInterface, ISecondInterface} _foo; public void SetFoo({IFirstInterface, ISecondInterface} value) { _foo = value; } 要求: 我没有能力向大多数将被传递到Foo的类型添加接口。因此,我无法创建从IFirstInterface和ISecondInterface继承的第三个接口 如果可能的话,我希望避

类似于。我想指定一个变量实现多个接口。比如说

private {IFirstInterface, ISecondInterface} _foo;

public void SetFoo({IFirstInterface, ISecondInterface} value)
{
    _foo = value;
}
要求:

  • 我没有能力向大多数将被传递到Foo的类型添加接口。因此,我无法创建从IFirstInterface和ISecondInterface继承的第三个接口
  • 如果可能的话,我希望避免将包含类设置为泛型,因为Foo的类型与该类没有太多关系,而且用户在编译时也不太可能知道它
  • 以后我需要使用foo来访问这两个接口中的方法
  • 我希望以一种编译器安全的方式来实现这一点,也就是说,在尝试使用接口之前,不要试图强制转换接口。如果foo不同时实现这两个接口,很多功能将无法正常工作
这可能吗


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

在.NET中的变量有一个类型,类型可以实现多个接口。大概是这样的:

public interface Interface1 { }
public interface Interface2 { }
public class SupportsMuliple : Interface1, Interface2 { }
ConcreteType bar = new ConcreteType(); // this implements both

Foo(bar);

但从您的问题来看,您似乎希望让一个变量实现多个接口,而不需要实现这些接口的类型。这实际上是不可能的,但是您可以动态地生成一个实现接口的类型,并隐藏一个事实,即有一个真正的类型在发挥作用。模拟库使用。

如果您想约束方法
SetFoo
只获取实现这两个接口的参数,那么您就幸运了:

public void SetFoo<T>(T value) where T : IFirstInterface, ISecondInterface
{
    _foo = value;
}

显然,这是否真的有意义取决于您的具体场景。您一定要仔细考虑,因为具有此类约束的类有时会导致一些您可能没有预料到的问题(例如,
SetFoo
现在必须采用
T
类型的参数,而不仅仅是实现两个接口的任何类)。

不,无法以声明方式确保特定实例实现多个接口

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

public void Foo<T>(T arg)
    where T : IFirstInterface
    where T : ISecondInterface
{
    ...
}

可以定义接口,以便以类型安全的方式需要和使用它们的任意组合。关键是定义一个接口ISelf(Of Out T),它的一个成员Self是一个属性,通过该属性,对象将自身返回为T,然后对于每个接口IFoo,声明一个形式为IFoo(Of Out T)的对应泛型,它继承自IFoo和ISelf(Of T)。实现ISelf(Wowzo的)、IFoo(Wowzo的)、IBar(Wowzo的)和IBoz(Wowzo的)的类Wowzo将实现IFoo(IBar的)、IBar(IFoo的)、IFoo(IBoz的)(IBar的))、IFoo(IBar的)(IFoo)(IBar的)(IBoz的)等,并在必要时可以被类型转换为任何此类类型。如果Thing是一个IFoo(属于IBar(属于IBoz)),那么可以直接将其用作IFoo,或者将Thing.Self用作IBar,或者将Thing.Self.Self用作IBoz

使用C#以这种方式组合三个接口的示例:

公共接口本身
{
T Self{get;}
}
接口IA{}
接口IA:IA,ISelf{}
接口IB{}
接口IB:IB,ISelf{}
接口IC{}
接口IC:IC,ISelf{}
类具体事物
:IA
,IB
,IC
{
公共实体自身=>这个;
}
公共类引用对象
{
一件事{get;}
void方法()
{
IA=事物;
ibb=事物自身;
IC c=Thing.Self.Self;
}
}

简短回答:否。如果不定义继承自IFirstInterface和ISecondInterface的第三个接口,就不能这样做。我唯一的想法是,可以将同一个实例作为两个接口变量?你在什么情况下需要这个?你能提供一些关于你在做什么的见解吗?你需要这样的东西吗?所以我不反对创建一个简单的类来处理这个问题。@drachenstern这些类已经存在了。假设这两个接口是IList和INotifyCollectionChanged。用户可以提供ObservableCollection、ReadOnlyObservableCollection、CompositeCollection、FreezableCollection或ObservableDictionary。除了ObservateDictionary之外,这些都内置在.Net中。我也有过很多实例,我希望其中一个接口是ISerializable的。@Bryan Anderson-是的,但是如果它是一个合适的类,那么它可以同时获得这两个接口,并且你不必做时髦的语义或强制转换,对吗?我想如果它能让代码更简单,它会工作的,但我只是觉得读起来有点难。谢谢你的回复。实现接口的类型已经存在,我只需要以一种与实现无关的方式存储和使用它们。如果从
T
的约束中删除
IFirstInterface
,它将成为运行时强制转换。但您可以,例如,执行
IFirstInterface\u foo first=\u foo
或。
ConcreteType bar = new ConcreteType(); // this implements both

Foo(bar);
public interface ISelf<out T>
{
    T Self { get; }
}
interface IA { }
interface IA<T> : IA, ISelf<T> { }
interface IB { }
interface IB<T> : IB, ISelf<T> { }
interface IC { }
interface IC<T> : IC, ISelf<T> { }
class ConcreteThing
    : IA<ConcreteThing>
    , IB<ConcreteThing>
    , IC<ConcreteThing>
{
    public ConcreteThing Self => this;
}
public class ReferencingObject
{
    IA<IB<IC>> Thing { get; }

    void Method()
    {
        IA a = Thing;
        IB b = Thing.Self;
        IC c = Thing.Self.Self;
    }
}