我有以下代码:
T imageCollectionItem;
// This checks if image actually exists, if it doesn't it gets the next best one... Thumbnail wil always exist so it will always find one
imageCollectionItem = (this.ResizedImageCollection
.Where(x => ((IBaseImage)x).Image.ImageSizeType.Key != ImageSizeType.Original)
.OrderByDescending(x => ((IBaseImage)x).Image.ImageSizeType.Key == imageSizeTypeKey)
.ThenBy(x => ((IBaseImage)x).Image.ImageSizeType.Order)
.FirstOrDefault());
if( imageCollectionItem != null )
{
return ((IBaseImage)imageCollectionItem).Image; // Compiles fine
return (IBaseImage)imageCollectionItem.Image; // Fails
}
(cast)variable
和((cast)variable)
之间的区别是什么?
考虑一个编译,一个不是
答案 0 :(得分:3)
运营商有一个优先顺序。 Cast位于Unary" block"中,而成员访问位于Primary" block"中。主块优先于一元块。首先执行主块操作符(成员访问),然后执行强制转换操作符(一元块)。显然,由于类型错误,无法执行成员访问。编译错误。
请参阅https://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx和(更新)https://msdn.microsoft.com/en-us/library/ms173145.aspx。
答案 1 :(得分:3)
if( imageCollectionItem != null )
{
return ((IBaseImage)imageCollectionItem).Image; // Compiles fine
return (IBaseImage)imageCollectionItem.Image; // Fails
}
第一行运行是因为.Image
在已转换为正确接口的对象上运行。
在第二行中,在之后调用.Image
属性之前,您不会将其强制转换 - 我认为这会导致“未找到成员”错误或类似错误。
答案 2 :(得分:1)
这不编译:
(IBaseImage)imageCollectionItem.Image;
因order of precedence(一元)和cast-operator(小学)的dot operator而异。前者的优先级低于后者。因此,编译器首先尝试执行此语句:
imageCollectionItem.Image
这不会编译,因为此时imageCollectionItem
不是IBaseImage
。
通过将其包装在括号中,您告诉编译器它应该在执行点运算符之前将其作为块执行:
((IBaseImage)imageCollectionItem).Image // an IBaseImage now
答案 3 :(得分:0)
return ((IBaseImage)imageCollectionItem).Image;
在这个return语句中,只有imageCollectionItem会被转换为IBaseImage。
return (IBaseImage)imageCollectionItem.Image;
整个return语句将被转换。
答案 4 :(得分:0)
((TypeX)ObjectA).PropertyOfTypeX; // Compiles fine
因为您首先将ObjectA转换为TypeX,然后引用属性PropertyOfTypeX
(TypeX)ObjectA.PropertyOfTypeX; // won't work
因为在将ObjectA转换为TypeX之前尝试访问属性PropertyOfTypeX。在这种情况下,您尝试将PropertyOfTypeX从ObjectA转换为TypeX。在我们的例子中,PropertyOfTypeX在ObjectA上不存在。
答案 5 :(得分:0)
让我们分解这两个陈述,看看他们究竟想做什么。通过这种方式,可以很容易地看到第二个语句在转换之前尝试访问该属性。
首先,
// return ((IBaseImage)imageCollectionItem).Image; // Compiles fine
var casted = (IBaseImage)imageCollectionItem; // cast to IBaseImage
return casted.Image; // access the Image property
其次,
// return (IBaseImage)imageCollectionItem.Image; // Fails
var noCast = imageCollectionItem.Image; // doesn't work becuse Image is not a memebr of imageCollectionItem
return (IBaseImage)noCast;