为什么不能将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属性?

为什么不能将MediaItem强制转换为SecureMediaItem ?

No。这与扩大阵容正好相反。SecureMediaItemMediaItem更特异。您可以将SecureMediaItem转换为MediaItem,因为SecureMediaItemMediaItem。另一种方法是行不通的,因为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。这类似于将形状视为正方形:当形状为正方形时,它将起作用,但当它是圆形时则不起作用。

有一种方法可以解决这个问题:定义自己的显式转换操作符。但是,我不建议使用它,因为它会对对象层次结构进行快速和松散的处理。