gpt4 book ai didi

c# - Liskov 替换和合成

转载 作者:太空狗 更新时间:2023-10-29 17:38:45 25 4
gpt4 key购买 nike

假设我有这样一个类:

public sealed class Foo
{
public void Bar
{
// Do Bar Stuff
}
}

我想扩展它以添加超出扩展方法所能做的事情....我唯一的选择是组合:

public class SuperFoo
{
private Foo _internalFoo;

public SuperFoo()
{
_internalFoo = new Foo();
}

public void Bar()
{
_internalFoo.Bar();
}

public void Baz()
{
// Do Baz Stuff
}
}

虽然这行得通,但需要做很多工作……但是我仍然遇到了一个问题:

  public void AcceptsAFoo(Foo a)

我可以在这里传递一个 Foo,但不能传递一个 super Foo,因为 C# 不知道 SuperFoo 确实符合 Liskov 替换的意义……这意味着我通过组合扩展类的用途非常有限。

因此,解决它的唯一方法是希望原始 API 设计者留下一个接口(interface):

public interface IFoo
{
public Bar();
}

public sealed class Foo : IFoo
{
// etc
}

现在,我可以在 SuperFoo 上实现 IFoo(因为 SuperFoo 已经实现了 Foo,只需更改签名即可)。

public class SuperFoo : IFoo

在完美的世界中,使用 Foo 的方法将使用 IFoo 的:

public void AcceptsAFoo(IFoo a)

现在,由于公共(public)接口(interface),C# 理解了 SuperFoo 和 Foo 之间的关系,一切都很好。

最大的问题是 .NET 密封了许多偶尔会很好扩展的类,并且它们通常不实现通用接口(interface),因此采用 Foo 的 API 方法不会接受 SuperFoo 而你不能添加重载。

那么,对于那里的所有组合粉丝......你如何绕过这个限制?

我唯一能想到的就是将内部的 Foo 公开,这样你就可以偶尔传递它,但这看起来很乱。

最佳答案

在我开始研究自己的可重用库之前,我发现自己也在问同样的问题。很多时候,您最终会得到某些类,如果不要求来自实现者的模糊或晦涩的调用序列,这些类就无法扩展。

当允许扩展你的类时,你必须问:如果开发人员扩展我的类,并将这个新类传递到我的库中,我可以透明地使用这个新类吗?我可以正常使用这个新类(class)吗?这个新类真的会表现得一样吗?

我发现大多数情况下,.Net Framework 中的密封类都有一些您不知道的底层要求,并且鉴于当前的实现不能安全地暴露给子类。

这并不能完全回答您的问题,但它提供了关于为什么并非所有类在 .Net Framework 中都是可继承的(以及为什么您也应该考虑密封一些类)的见解。

关于c# - Liskov 替换和合成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/554145/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com