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 等)实现一个接口(interface)(例如 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)
}
所以声明很快就会变得笨拙。
我可以用什么设计模式来实现:
- 许多实现接口(interface) ISomeInterface 的具体类 AND
- 使用实现必要接口(interface) IIn、IOut 的具体参数/返回值?
ISomeInteface 上将有许多方法,它们具有不同类型的参数/接口(interface)组合。
最佳答案
让我们简化问题。假设我们有:
class Animal {}
class Giraffe : Animal {}
interface IFoo
{
Animal M();
}
那我们能不能
class C : IFoo
{
public Giraffe M() => new Giraffe();
}
不幸的是没有。接口(interface)实现必须完全匹配。
现在,您可能会想“嘿,界面要求返回动物,而我要返回动物,即长颈鹿,那有什么问题吗?”
答案是没有问题。 C# 可以有一个可用的类型系统,这个特性已经被提出了很多很多次。它称为“返回类型协方差”,如果您在此处进行搜索,您会发现很多关于它的问题。
但是 C# 没有这个功能,所以你运气不好。你能做的最好的事情是:
class C : IFoo
{
Animal IFoo.M() => this.M();
public Giraffe M() => new Giraffe();
}
现在你很好了。 IFoo
契约被显式实现,类的公共(public)表面具有更具体的签名。
类似地,如果我们有:
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
说一个实现必须能够接受任何动物,所以你不能用只接受长颈鹿的方法来实现它。从逻辑上讲,返回类型变得更具体是安全的,但形式参数类型必须不那么具体。这就是为什么它是返回类型 co 变体但形式参数类型是 contra 变体的原因,因为在相反情况下可转换性的方向会发生变化。
关于c# - 声明具体实现具有具体类型的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49290959/