声明一个具体实现具有具体类型的接口

时间:2018-03-15 03:10:12

标签: c# design-patterns

public interface ISomeInterface
{
    IOut SomeMethod(IIn aIn)
}

public class MyOut : IOut
{
    public string AnExtraProp {get; set;}
}

public class MyIn : IIn
{
    public string AnotherExtraProp {get; set;}    }
}

public class MyConcreteOfSomeInterface : ISomeInterface
{
     public MyOut SomeMethod(MyIn aIn)
     {
     }
} 

是否有可能有许多类(例如MyConcreteOfSomeInterface,MyConcrete2OfSomeInterface,....)实现一个接口(例如ISomeInterface)但是具有具体类型的参数(例如MyIn,MyOut等)。

我意识到我可以声明:

public interface ISomeInterface<TIn, TOut>
{
    TOut SomeMethod(TIn aIn)
}

但由于ISomeInterface将有许多方法,这将是不切实际的。所以说我需要添加其他方法SomeMethod2和SomeMethod3然后我最终会得到:

public interface ISomeInterface<TIn, TOut, TIn2, TOut2, TIn3, TOut3>
{
    TOut SomeMethod(TIn aIn)
    TOut2 SomeMethod(TIn2 aIn)
    TOut3 SomeMethod(TIn3 aIn)
}

所以声明很快变得笨拙。

我可以使用哪种设计模式来实现:

  1. 许多实现接口ISomeInterface AND
  2. 的具体类
  3. 使用实现必要接口IIn,IOut?
  4. 的具体参数/返回值

    ISomeInteface上有许多方法,参数/接口组合的类型不同。

1 个答案:

答案 0 :(得分:3)

让我们简化问题。假设我们有:

class Animal {}
class Giraffe : Animal {}
interface IFoo 
{
  Animal M(); 
}

我们可以拥有

class C : IFoo
{
  public Giraffe M() => new Giraffe();
}

不幸的是没有。接口实现必须与完全匹配

现在,你可能会认为,嘿,界面要求动物被归还,我要归还动物,即长颈鹿,那么问题是什么?&#34;

答案是没有问题。 C#可以有一个类型系统,这个功能已被提出很多次了。它被称为&#34;返回类型协方差&#34;,如果你在这里搜索,你会发现很多问题。

但是C#没有这个功能,所以你运气不好。你能做的最好的是:

class C : IFoo 
{
  Animal IFoo.M() => this.M();
  public Giraffe M() => new Giraffe();
}

现在你很好。 IFoo合约已明确实施,并且该类的公共表面具有更具体的签名。

同样,如果我们有:

interface IBar() 
{
  void N(Giraffe g); 
}

这不合法:

class D : IBar
{
  public void N(Animal g) { ... }
}

同样,这将是非常明智的。 IBAR要求D.N是你可以通过长颈鹿的东西,而D.N是你可以通过长颈鹿或任何动物的东西。但同样,C#不支持此功能。这称为形式参数逆变,只有极少数编程语言支持它。

搜索C#协方差和逆变,了解C#支持 的方差类型的详细信息。

另请注意,这不是类型安全的:

interface IBaz 
{
  void P(Animal a);
}
class E : IBaz
{
  public void P(Giraffe g) { } 
}

因为您需要能够说((IBaz)(new E())).P(new Tiger())IBaz表示实现必须能够接受任何动物,因此您无法使用仅接受长颈鹿的方法来实现它。从逻辑上讲,返回类型更安全,但正式参数类型必须 less 特定。这就是为什么它返回类型 co <​​/ em>方差但是形式参数类型反对方差,因为可兑换的方向在相反的情况下会发生变化。