c# as operator

  • Thread starter Thread starter KShvats
  • Start date Start date
K

KShvats

Hey there

Which is better: "(inSet as ICloneable).Clone()" or
"((ICloneable)inSet).Clone()"?

Thank you
 
Neither.
If inSet is not IClonable, then both alternatives will result in an
exception (null.Clone() will also throw an exception).

For this case, you'd be better off to do:
IClonable foo = inSet as IClonable;
foo.Clone();
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
Oops - should have been:
IClonable foo = inSet as IClonable;
if (foo != null)
foo.Clone();
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
You should review the meaning of "as" in C#.
The reason you would use "as" is so that the cast attempt yields null
instead of an exception if the cast fails. Combining "as" with the method
call in one statement will trigger an exception if the cast fails because
null.<method call> will cause the exception. So you just get a different
kind of exception in that case than if you'd just done a straight cast. If
you are sure that the cast will be successful, then just do the straight cast.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
David said:
So you just get a different
kind of exception in that case than if you'd just done a straight cast.

To elaborate a bit on this, the straight cast will give you an
exception that says that your inSet does not support IClonable. Pretty
straightforward. The `as` cast will give you a null-dereference
exception, which means you'd have to look at the code and translate a
null-dereference to "Oh, inSet does not support IClonable."
 
David Anton said:
Neither.
If inSet is not IClonable, then both alternatives will result in an
exception (null.Clone() will also throw an exception).

For this case, you'd be better off to do:
IClonable foo = inSet as IClonable;
foo.Clone();

I disagree - if you use the above code, you'll get a
NullReferenceException, which means you won't know if inSet was null or
whether it wasn't an IClonable. It also doesn't really indicate the
problem.

If you use ((IClonable)inSet).Clone() then if inSet *is* a non-null
reference but to something which doesn't implement IClonable, the
exception which is thrown makes it much more obvious what's going on.
 
Yeah - I saw my error immediately after posting (see my reply to my reply).
It was early and the coffee hadn't made its way to my system yet.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: VB to Python converter
 
Jon Shemitz said:
To elaborate a bit on this, the straight cast will give you an
exception that says that your inSet does not support IClonable. Pretty
straightforward. The `as` cast will give you a null-dereference
exception, which means you'd have to look at the code and translate a
null-dereference to "Oh, inSet does not support IClonable."

Which, to answer the original question, means that

((ICloneable)inSet).Clone()

is right.

And

(inSet as ICloneable).Clone()

is wrong.

David
 
"Casting impact and performance in C#
I'll try here to discuss the difference between the two types of casting.
C# provides two ways for casting object references

object myClass = new MyClass();
((MyClass)myClass).MyMethod();


This is an example of downcasting (casting from the top to the bottom of
the class hierarchy).

In the first line of code, the compiler emits a "Castclass" opcode,
which converts the reference to the type specified between the
parenthesis if possible (if not, an InvalidCastException exception is
thrown).

The second case is :

object myClass = new MyClass();
(myClass as MyClass).MyMethod();

here we use the as operator , which works much faster, because it only
checks the reference type but doesn't perform any sort of cast (nor
throws any exception).

In performance terms, it is better to use the second option, because it
speeds up much more the code execution, avoiding type casts and
exception throwing."

http://msdonet.blogspot.com/
 
KShvats said:
"Casting impact and performance in C#
I'll try here to discuss the difference between the two types of casting.
C# provides two ways for casting object references

object myClass = new MyClass();
((MyClass)myClass).MyMethod();


This is an example of downcasting (casting from the top to the bottom of
the class hierarchy).

In the first line of code, the compiler emits a "Castclass" opcode, which
converts the reference to the type specified between the parenthesis if
possible (if not, an InvalidCastException exception is thrown).

The second case is :

object myClass = new MyClass();
(myClass as MyClass).MyMethod();

here we use the as operator , which works much faster, because it only
checks the reference type but doesn't perform any sort of cast (nor throws
any exception).

In performance terms, it is better to use the second option, because it
speeds up much more the code execution, avoiding type casts and exception
throwing."

http://msdonet.blogspot.com/

Any performance difference here is on the wrong order of magnitude to affect
the question of which formulation is better.

It's exactly the exception-throwing behavior that makes the downcast the
right method. In certain performance-constrained applications you might
want to sacrifice the
debugability of the code for the last ounce of performance, but those are
rare edge cases.

David
 
KShvats said:
object myClass = new MyClass();
((MyClass)myClass).MyMethod();
In the first line of code, the compiler emits a "Castclass" opcode,
which converts the reference to the type specified between the
parenthesis if possible (if not, an InvalidCastException exception is
thrown).
object myClass = new MyClass();
(myClass as MyClass).MyMethod();

here we use the as operator , which works much faster, because it only
checks the reference type but doesn't perform any sort of cast (nor
throws any exception).

This is just not true. The left-cast returns a reference of the new
type, if it can, and raises an exception if it can't. The right-cast
returns a reference of the new type, if it can, and returns null if it
can't.

That is, inside the CLR, these are doing identical checks, and differ
only in the `else` clause. There's no reason to expect a successful
left-cast to be any faster or any slower than a successful right-cast.
In performance terms, it is better to use the second option, because it
speeds up much more the code execution, avoiding type casts and
exception throwing."

This is a garbled version of a valid tip.

Expected Reference = Object as Expected;
if (Reference != null)
Reference.Whatever();

is significantly faster than

if (Object is Expected)
(Reference)Object.Whatever();

because the `is` operator is doing the same type check that the cast
does.

Not exactly a reputable source - the author posts no credentials, and
can't even spell "dot".
 
Back
Top