Jimmyt1988
Jimmyt1988

Reputation: 21186

What's the difference between (cast)variable and ((cast)variable)

I have the following code:

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
}

What's the difference between (cast)variable and ((cast)variable)?

Considering one compiles and one doesn't?

Upvotes: 1

Views: 98

Answers (6)

xanatos
xanatos

Reputation: 111940

There is an order of precedence for operators. Cast is in the Unary "block", while member access is in the Primary "block". Primary block has more priority than Unary block. First the Primary block operator (member access) would be executed, then the cast operator (Unary block). Clearly the member access can't be executed because the type is wrong. Compilation error.

See https://msdn.microsoft.com/en-us/library/aa691323(v=vs.71).aspx and (newer) https://msdn.microsoft.com/en-us/library/ms173145.aspx .

Upvotes: 3

ceuben
ceuben

Reputation: 329

return ((IBaseImage)imageCollectionItem).Image;

In this return-statement, only imageCollectionItem will be casted to IBaseImage.

return (IBaseImage)imageCollectionItem.Image;

The whole return-statement will be casted.

Upvotes: 0

wonderbell
wonderbell

Reputation: 1126

Lets break down these two statements and see what exactly they are trying to do. This way it will be simple to see that the second statement is trying to access the property before casting.

First,

// return ((IBaseImage)imageCollectionItem).Image; // Compiles fine
var casted = (IBaseImage)imageCollectionItem; // cast to IBaseImage
return casted.Image; // access the Image property

Second,

//  return (IBaseImage)imageCollectionItem.Image; // Fails
var noCast = imageCollectionItem.Image; // doesn't work becuse Image is not a memebr of imageCollectionItem
return (IBaseImage)noCast;

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460308

This doesn't compile:

(IBaseImage)imageCollectionItem.Image; 

because of the order of precedence of the cast-operator(Unary) and the dot operator(Primary). The former has a lower precedence than the latter. For that reason the compiler tries to execute this statement first:

imageCollectionItem.Image

That doesn't compile because imageCollectionItem is not an IBaseImage at this point.

By wrapping it in parentheses you tell the compiler that it should execute this as a block before the dot-operator is executed:

((IBaseImage)imageCollectionItem).Image // an IBaseImage now

Upvotes: 2

z0mbi3
z0mbi3

Reputation: 346

((TypeX)ObjectA).PropertyOfTypeX; // Compiles fine

because you first convert ObjectA to TypeX and then refer to property PropertyOfTypeX

(TypeX)ObjectA.PropertyOfTypeX; // won't work

because you try to access property PropertyOfTypeX before you convert ObjectA to TypeX. In this case you tried to convert PropertyOfTypeX from ObjectA to TypeX. PropertyOfTypeX doesn't exists on ObjectA in our case.

Upvotes: 0

TZHX
TZHX

Reputation: 5398

if( imageCollectionItem != null )
{
    return ((IBaseImage)imageCollectionItem).Image; // Compiles fine
    return (IBaseImage)imageCollectionItem.Image; // Fails
}

The first line runs because the .Image is run on an object that has been cast to the correct interface.

In the second line, you are not casting it until after calling the .Image property -- which I assume results in a "Member not found" error or similar.

Upvotes: 3

Related Questions