如何以通用方法允许派生的收集



i有多个代表对象的类,这些对象都具有由unity rect字段描述的界限。(Zone, Room, Structure, Tunnel, Room ...(

这些对象通常放在集合中。(List<Zone>, List<Room> ...(

我想拥有单个静态实用方法,该方法将测试这些对象集合中的任何一个界限,而无需使用linq。

public static bool BoundsOverlapsOtherBounds(Bounds bound, List<Bounds>)

我应该如何使用C#多态性,界面,协方差来实现这一目标,而无需首先将List<Room>List<Zone>施放到List<Bounds>

到目前为止,我的尝试始终产生的" 无法掩盖x至y" 编译器错误。

因为(如所暗示(所有这些类型已经从Bounds继承而来,因此您无需将List<Room>List<Zone>施放到List<Bounds>

您可以做到这一点:

bool BoundsOverlapsOtherBounds<T>(Bounds bound, List<T> bounds) where T : Bounds

通用约束意味着您可以将任何List<T>传递给该方法,只要T实现或继承Bounds

因此,如果您有List<Room>,则可以将其传递给该方法,而无需明确施放:

var rooms = new List<Room>();
var otherBounds = new Bounds();
var overlaps = BoundsOverlapsOtherBounds(otherBounds, rooms);

您甚至不必指定通用参数,因为它是推断的。


如果这些对象没有共同的类型,则可能是应有的情况。继承是 a 解决方案,但我们不需要使用它来使类型具有共同的特征。有时,这会使我们进入角落。接口也可能有意义:

interface IHasBoundaries // not a great name?
{
    Boundaries Bounds { get; }
}

那是多态性。多种形式(或类型(可以实现界面,您根本不在乎什么使它们与众不同 - 只有它们的共同点。您可以编写有关IHasBoundaries的代码,在这种情况下,这是您唯一需要了解的对这些对象的信息,它们实现了接口。

然后您的方法看起来像这样:

bool BoundsOverlapsOtherBounds<T>(IHasBoundaries bound, List<T> bounds) 
    where T : IHasBoundaries

问题是List<Zone>List<Bounds>不同。您可以将Room添加到List<Bounds>,但不能将其添加到List<Zone>中,这就是为什么无法转换它们的原因。但是,我认为您只想迭代范围列表而不是更改集合,为此,您只需要IEnumerable而不是List。由于IEnumerable<Zone>的功能与IEnumerable<Bounds>相同。因此,如果您确实只想阅读bounds参数的元素,请将签名更改为:

public static bool BoundsOverlapsOtherBounds(Bounds bound, IEnumerable<Bounds> bounds)

应该接受(Zone, Room, …)的任何List

希望这有帮助

相关内容

  • 没有找到相关文章

最新更新