Home All Groups Group Topic Archive Search About
Author
26 Nov 2006 12:18 PM
KShvats
Hey there

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

Thank you

Author
26 Nov 2006 2:58 PM
David Anton
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


Show quote
"KShvats" wrote:

> Hey there
>
> Which is better: "(inSet as ICloneable).Clone()" or
> "((ICloneable)inSet).Clone()"?
>
> Thank you
>
Author
26 Nov 2006 3:13 PM
David Anton
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


Show quote
"David Anton" wrote:

> 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
>
>
> "KShvats" wrote:
>
> > Hey there
> >
> > Which is better: "(inSet as ICloneable).Clone()" or
> > "((ICloneable)inSet).Clone()"?
> >
> > Thank you
> >
Author
26 Nov 2006 7:39 PM
Jon Skeet [C# MVP]
David Anton <DavidAn***@discussions.microsoft.com> wrote:
> 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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Author
26 Nov 2006 8:12 PM
David Anton
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


Show quote
"Jon Skeet [C# MVP]" wrote:

> David Anton <DavidAn***@discussions.microsoft.com> wrote:
> > 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.
>
> --
> Jon Skeet - <sk***@pobox.com>
> http://www.pobox.com/~skeet   Blog: http://www.msmvps.com/jon.skeet
> If replying to the group, please do not mail me too
>
Author
26 Nov 2006 3:43 PM
David Anton
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


Show quote
"KShvats" wrote:

> Hey there
>
> Which is better: "(inSet as ICloneable).Clone()" or
> "((ICloneable)inSet).Clone()"?
>
> Thank you
>
Author
26 Nov 2006 7:10 PM
Jon Shemitz
David Anton wrote:

> 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."

--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.
Author
27 Nov 2006 2:04 AM
David Browne
"Jon Shemitz" <j**@midnightbeach.com> wrote in message
news:4569E69D.D61F7D3C@midnightbeach.com...
> David Anton wrote:
>
>> 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."
>

Which, to answer the original question, means that

  ((ICloneable)inSet).Clone()

is right.

And

  (inSet as ICloneable).Clone()

is wrong.

David
Author
27 Nov 2006 8:42 AM
KShvats
"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/

David Browne wrote:
Show quote
>
>
> "Jon Shemitz" <j**@midnightbeach.com> wrote in message
> news:4569E69D.D61F7D3C@midnightbeach.com...
>> David Anton wrote:
>>
>>> 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."
>>
>
> Which, to answer the original question, means that
>
>  ((ICloneable)inSet).Clone()
>
> is right.
>
> And
>
>  (inSet as ICloneable).Clone()
>
> is wrong.
>
> David
Author
27 Nov 2006 4:46 PM
David Browne
Show quote
"KShvats" <z@z.z> wrote in message
news:ONUCSBgEHHA.3600@TK2MSFTNGP06.phx.gbl...
> "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
Author
27 Nov 2006 7:08 PM
Jon Shemitz
KShvats wrote:

Show quote
> 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".

--

..NET 2.0 for Delphi Programmers
www.midnightbeach.com/.net
What you need to know.

AddThis Social Bookmark Button