我有多个表示对象的类,这些对象都具有由Unity Rect字段描述的范围。 (Zone, Room, Structure, Tunnel, Room
...)
这些对象通常放置在集合中。 (List<Zone>, List<Room>
...)
我希望有一个静态实用工具方法,该方法将测试其中一个是否与此类对象集合中的任何边界重叠,而不必使用LINQ强制转换List。
public static bool BoundsOverlapsOtherBounds(Bounds bound, List<Bounds>)
我应该如何使用C#多态性,接口,协方差来实现此目的,而无需首先将List<Room>
或List<Zone>
强制转换为List<Bounds>
?
到目前为止,我的尝试始终会产生“ 无法将X转换为Y” 编译器错误。
答案 0 :(得分:1)
由于(暗含的)所有这些类型已经从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
答案 1 :(得分:0)
问题在于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)
参数的元素,请将签名更改为:
List
应接受(Zone, Room, …)
中的任何Partial
希望这会有所帮助