为什么不能将MediaItem强制转换为SecureMediaItem ?
本文关键字:转换 SecureMediaItem 不能 MediaItem 为什么 | 更新日期: 2023-09-27 18:06:21
我有类:
[DataContract]
public class MediaItem : Video
{
//used to protect calling api from the incorrectly named video
}
[DataContract]
public class SecureMediaItem : MediaItem
{
[DataMember]
public PlayerEmbedToken Token;
}
然后我有以下代码:
List<MediaItem> dummyItems = new List<MediaItem>();
//cast the media item into a secure media item
SecureMediaItem retItem = (SecureMediaItem)dummyItems[mediaId];
//TODO: put in the Admin ID
retItem.Token.UserId = 1;
retItem.Token.IpAddress = VLSCore2.VlsSecurity.ParseIpFromString(ipAddress);
retItem.Token.UniquePlayerRef = Guid.NewGuid().ToString();
return retItem;
但是我得到一个错误:
无法强制转换类型的对象"VLSCore2.Entities.Security.Api。输入MediaItem"VLSCore2.Entities.Security.Api.SecureMediaItem"。
这只是一个简单的扩展强制转换,不是吗?比如DataContract属性?
No。这与扩大阵容正好相反。SecureMediaItem
比MediaItem
更特异。您可以将SecureMediaItem
转换为MediaItem
,因为SecureMediaItem
是MediaItem
。另一种方法是行不通的,因为MediaItem
不一定是SecureMediaItem
。
除了@Daniel的话,可能更直观的理解这一点,如果你把MediaItem
想象成一个圆圈,把它延伸你就得到了一个更大的圆圈SecureMediaItem
。在这种情况下,铸造就像切割你选择的圆圈。你不能把切成更小的圆来得到更大的圆。
这是…
您得到的错误是有意义的:您有一个父项列表,但是您试图执行向下强制转换。标准的例子是这样的:
public class Shape { ... }
public class Circle : Shape
{
public void FillCircle();
}
public class Square : Shape
{
public void FillSquare();
}
...
Shape s = new Circle();
s.FillCircle(); // won't compile
Circle c = (Circle) s;
c.FillCircle(); // dangerous, but works
Square sq = (Square) s; // runtime error
转换为Circle有效,因为特定的形状恰好是Circle。然而,转换为Square会失败,因为虽然Square是Shape,但Shape不一定是Square,而Circle肯定不是Square。
在您的例子中,您试图像对待SecureMediaItem一样对待MediaItem。这类似于将形状视为正方形:当形状为正方形时,它将起作用,但当它是圆形时则不起作用。
有一种方法可以解决这个问题:定义自己的显式转换操作符。但是,我不建议使用它,因为它会对对象层次结构进行快速和松散的处理。