c# Casting v As operator
-
Ennis Ray Lynch, Jr. wrote:
AS should use IS and not the other way around
How that? 'a as B' should be compiled to 'a is B ? (B)a : null'? That would be horribly stupid. Consider how this works on the assembly level: 'is' is a function that takes an object and a type token, performs a type test, returns non-zero if successful, zero otherwise. 'as' is a function that takes an object and a type token, performs a type test, returns the object if successful, null otherwise. Given that objects are non-zero by definition, it makes perfect sense to use the same function for both, and that's exactly what .NET does. What's stupid is that the JIT optimizer is so dumb that this leads to a performance difference visible to the programmer. If the JIT could simply optimize away redundant casts, nobody would have to care what as/is/casts compile to.
What do you think AS is doing now?
Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
As others have probably pointed out (but I'm too lazy to read the rest of the thread), the two versions do different things. 'A' throws an
InvalidCastException
if the cast isn't possible. 'B' setsobj
tonull
if the cast doesn't work. Both are valid approaches, depending on the rest of your code.Software Zen:
delete this;
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
Like others have mentioned, us "as" when the object may be the wrong type. Also, "as" cannot be used for non-reference types (e.g.,
int
).Help a brotha out and vote Managing Your JavaScript Library in ASP.NET as the best ASP.NET article of May 2011.
-
I seem to have upset some voters along the way. :-D
It all balances out in the long run :)
www.software-kinetics.co.uk Wear a hard hat it's under construction
-
As is for poor programmers. If you know that e always is SomeObject then e should be typed as such using some other method. Otherwise you always have to check the result of the as operation. So then you have the following two scenarios which must always be in case A or case B:
if(e is SomeObject){
SomeObject someObject = (SomeObject)e;
}or
SomeObject someobject = e as SomeObject;
if(someObject != null){}
But then in case by I always here the response ... but I know e is always SomeObject. Really then maybe it should be defined as such. The AS operator is designed solely to support developers that don't have a fundamental concept of type. After all, for all of the time I have seen the is operator used with a subsequent cast, checking for null after the AS is a white rhinoceros.
Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost
Hear hear! Except for that I don't like your first example; I do that to pass the cast value to another method.
if(e is SomeObject){
F ( (SomeObject) e ) ;
}If I'm setting a variable or field I use
as
. -
Thanks Ennis - I'm a poor programmer then because I use
as
, rather than the double cast, which is doing the same work again. What happens internally withas
is that it checks to see if the variable is of the type, and if it is it returns a non-null pointer to that type. With theis
operator, you check to see if it is of the type and then you cast it - which still determines internally whether or not it belongs to that type (this is how it throws anInvalidTypeException
). In any case where you are using code-discovery, such as IoC, then theas
call is more efficient. [Edit]I should add that this relates to our plugin code where the client provides their own logic, and "forgets" to implement the appropriate interfaces.[/Edit]Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
modified on Thursday, June 23, 2011 9:30 AM
Pete O'Hanlon wrote:
and "forgets" to implement the appropriate interfaces.
Then you throw an Exception and don't allow that malformed plug-in.
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
"Note that the as operator only performs reference conversions and boxing conversions. The as operator cannot perform other conversions, such as user-defined conversions, which should instead be performed using cast expressions." Two of three C# books I have here don't mention
as
at all. -
I use the (cast) only when I know 'e is always SomeObject'. Which is a rare case - think stuff like
(ThisClass)base.MemberwiseClone()
. Otherwise, I preferas
+ null check overis
+ cast. It looks cleaner to me, and is also more performant. 'a is T
' gets compiled to the same IL as '(a as T) != null
', sois
+ cast ends up casting twice (and last time I checked, the JIT was too dumb to optimize that)." More formally, an expression of the form, Copyexpression as type is equivalent to, Copyexpression is type ? (type)expression : (type)null " http://msdn.microsoft.com/en-us/library/cscsdfbt(v=VS.80).aspx[^]
-
" More formally, an expression of the form, Copyexpression as type is equivalent to, Copyexpression is type ? (type)expression : (type)null " http://msdn.microsoft.com/en-us/library/cscsdfbt(v=VS.80).aspx[^]
Yes that's the specification of the behavior, but not how it's implemented.
Eric Lippert wrote:
The specification is clear on this point;
as
(in the non-dynamic case) is defined as a syntactic sugar foris
. However, in practice the CLR provides us instructionisinst
, which ironically acts likeas
. Therefore we have an instruction which implements the semantics ofas
pretty well, from which we can build an implementation ofis
. In short, de jureis
isis
, andas
is asis
is, but de factois
isas
andas
isisinst
.http://blogs.msdn.com/b/ericlippert/archive/2010/09/16/is-is-as-or-is-as-is.aspx[^]
-
You have better clients than we do then. You tell them, you must implement this interface in order for this to work, and bam they completely fail to implement the interface.
Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility
That's their problem.
-
PIEBALDconsult wrote:
what are you people doing?
SomeType obj = (SomeType)BloatedUglyUnreadableFrameworkFactory.CreateObject(someXMLStringThatIHopeWorksSometimesButNeverKnowForSure);
That deserves to blow up. What do you do once you've determined that it didn't work? Don't you just throw an Exception anyway?
-
Yes that's the specification of the behavior, but not how it's implemented.
Eric Lippert wrote:
The specification is clear on this point;
as
(in the non-dynamic case) is defined as a syntactic sugar foris
. However, in practice the CLR provides us instructionisinst
, which ironically acts likeas
. Therefore we have an instruction which implements the semantics ofas
pretty well, from which we can build an implementation ofis
. In short, de jureis
isis
, andas
is asis
is, but de factois
isas
andas
isisinst
.http://blogs.msdn.com/b/ericlippert/archive/2010/09/16/is-is-as-or-is-as-is.aspx[^]
I'll code to the spec and assume hope they'll fix the implementation.
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
b. it's better, because if the cast is wrong, the member would be null ... so you don't have to surround your code with a "try {} catch {}" every few lines. :)
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
For reference Type, should have to use 'As' operator because of if casting is not compatible with target Object then it return null while 'Casting' throws an exception. For Value Type,'As' operator doesnot work.
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
-
For those using c#, what do you prefer? A.
SomeObject obj = (SomeObject) e;
or B.
SomeObject obj = e as SomeObject;
www.software-kinetics.co.uk Wear a hard hat it's under construction
I guess this wasn't a serious question, but just in case somebody who doesn't know looks in, I prefer b as it won't throw an exception if the conversion is not possible, but rather will return a null. According to MSDN[^] it's equivalent to this:
expression is type ? (type)expression : (type)null
butexpression
is only evaluated once. -
I guess this wasn't a serious question, but just in case somebody who doesn't know looks in, I prefer b as it won't throw an exception if the conversion is not possible, but rather will return a null. According to MSDN[^] it's equivalent to this:
expression is type ? (type)expression : (type)null
butexpression
is only evaluated once.I suppose my argument on that, is the programmer should know if conversion will take place or not, than letting the code take control.
www.software-kinetics.co.uk Wear a hard hat it's under construction
-
Splitting hairs :)
www.software-kinetics.co.uk Wear a hard hat it's under construction
Not really, C style casts are not recommended in C++ last I checked. Its preferred to use the C++ casts
dynamic_cast<T>(x)
,static_cast<T>(x)
,reinterpret_Cast<T>(x)
andconst_cast<T>(x)
as they make the intention more explicit. See : Stroustrup[^] -
Not really, C style casts are not recommended in C++ last I checked. Its preferred to use the C++ casts
dynamic_cast<T>(x)
,static_cast<T>(x)
,reinterpret_Cast<T>(x)
andconst_cast<T>(x)
as they make the intention more explicit. See : Stroustrup[^]The final years of coding MFC, I was using the xxx_cast operators religously.
www.software-kinetics.co.uk Wear a hard hat it's under construction
-
I prefer
as
because it is safer:expression as type
is equivalent to:
expression is type ? (type)expression : (type)null
When you use casting you can get
StoopidTypeException
.
Panic, Chaos, Destruction. My work here is done. Drink. Get drunk. Fall over - P O'H OK, I will win to day or my name isn't Ethel Crudacre! - DD Ethel Crudacre I cannot live by bread alone. Bacon and ketchup are needed as well. - Trollslayer Have a bit more patience with newbies. Of course some of them act dumb - they're often *students*, for heaven's sake - Terry Pratchett
I fail to see why that is safer. In case (a), an exception can be raised if expression is of the wrong type. That seems entirely appropriate. In case (b), if an expression of the wrong type is supplied, the result is null. If a programmer fails to check this, the result is an exception anyway. There's a place for both of them. I generally prefer errors to generate exceptions early - i.e. at the cast, rather than the point of usage. So, if I really expect the result to be of a given type I use the former. If I'm using the cast as a shorthand for checking the type is OK, then casting, I prefer the latter.