我试图围绕C#(IEnumarable,IReadOnlyCollection)等所有列表接口,并且作为实现的一部分我不明白为什么下面的代码工作。毕竟,该方法有一个 IReadOnlyCollection 作为返回类型,但返回的varibale是Array类型(float [])。我意识到Array实现了IReadOnlyCollection接口,但我不知道它如何从一个转换为另一个。它是以某种方式在后台完成的吗?
private readonly float[] _location;
public Player()
{
_location = new float[3];
}
public IReadOnlyCollection<float> Location
{
get
{
_location[0] = Worker.Elements["lbXCoordinate"].Value;
_location[1] = Worker.Elements["lbYCoordinate"].Value;
_location[2] = Worker.Elements["lbZCoordinate"].Value;
return _location;
}
}
答案 0 :(得分:1)
对象可以隐式地转换为由其类实现的任何一个接口;但是,没有转换 - 正如Jon Skeet在评论中指出的那样,它是返回的原始数组。对于来电者来说,它将被伪装成#34;作为IReadOnlyCollection<float>
,理想情况下,调用者只能从IReadOnlyCollection<float>
执行操作。但是,如果调用者知道或怀疑实际类型,则调用者可能会决定将其强制转换为float[]
,并且将破坏对象的封装。 (但这对于调用者来说是有风险的,因为如果你在某个时候将实际类型更改为List<float>
,那么转换为float[]
的代码将会中断。)为了确保封装,对象是返回必须自己保护其内容,所以你应该确实创建一个私有(或没有)setter的类/结构。然后,您的代码也将变得更具可读性和自我记录。
答案 1 :(得分:-1)
上面的代码工作正常,因为IReadOnlyCollection接口实现了IEnumerable和Array抽象类也实现了IEnumerable接口。因此,当你为IReadOnlyCollection返回类型的方法返回float数组时,内部对IEnumerable进行向上转换。
我希望这就是你要找的东西。
答案 2 :(得分:-1)
不,Array没有实现IReadOnlyCollection,请参考以下链接: http://msdn.microsoft.com/en-IN/library/system.array(v=vs.110).aspx
并且IReadOnlyCollection也实现了相同的IEnumerable接口,请参考以下链接: http://msdn.microsoft.com/en-us/library/hh881542(v=vs.110).aspx
现在,当您尝试为类型为IReadOnlyCollection的方法返回一个数组时,它是一种类型安全的转换,它的基类型是IEnumerable。