NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

derived from the requested type, they fail. Casts, on the other hand, can use conversion operators to convert an object to the requested type. This includes any built-in numeric conversions. Casting a long to a short can lose information.
The same problems are lurking when you cast user-defined types. Consider this type:
public class SecondType
{
private MyType _value;
// other details elided
// Conversion operator.
// This converts a SecondType to
// a MyType, see item 9.
public static implicit operator
MyType(SecondType t)
{
return t._value;
}
}
Suppose an object of SecondType is returned by the Factory.GetObject() function in the first code snippet:
object o = Factory.GetObject();
// o is a SecondType:
MyType t = o as MyType; // Fails. o is not MyType
if (t != null)
{
// work with t, it's a MyType.
}
else
{
// report the failure.
}

(30) // Version two:
try
{
MyType t1;
t1 = (MyType)o; // Fails. o is not MyType
// work with t1, it's a MyType.
}
catch (InvalidCastException)
{
// report the conversion failure.
}
Both versions fail. But I told you that casts will perform user-defined conversions. You’d think the cast would succeed. You’re right—it should succeed if you think that way. But it fails because your compiler is generating code based on the compile-time type of the object, o. The compiler knows nothing about the runtime type of o; it views o as an instance of object. The compiler sees that there is no user-defined conversion from object to MyType. It checks the definitions of object and MyType. Lacking any user-defined conversion, the compiler generates the code to examine the runtime type of o and checks whether that type is a MyType. Because o is a SecondType object, that fails. The compiler does not check to see whether the actual runtime type of o can be converted to a MyType object.

You could make the conversion from SecondType to MyType succeed if you wrote the code snippet like this:
object o = Factory.GetObject();
// Version three:
SecondType st = o as SecondType;
try
{
MyType t;
t = (MyType)st;
// work with T, it's a MyType.
}
catch (InvalidCastException)
{
// report the failure.
}

(31) You should never write this ugly code , but it does illustrate a common problem. Although you would never write this, you can use an object parameter to a function that expects the proper conversions:
object o = Factory.GetObject();
DoStuffWithObject(o);
private static void DoStuffWithObject(object o)
{
try
{
MyType t;
t = (MyType)o; // Fails. o is not MyType
// work with T, it's a MyType.
}
catch (InvalidCastException)
{
// report the conversion failure.
}
}
Remember that user-defined conversion operators operate only on the compile-time type of an object, not on the runtime type. It does not matter that a conversion between the runtime type of o and MyType exists. The compiler just doesn’t know or care. This statement has different behavior, depending on the declared type of st:
t = (MyType)st;
This next statement returns the same result, no matter what the declared type of st is. So, you should prefer as to casts—it’s more consistent. In fact, if the types are not related by inheritance, but a user-defined conversion operator exists, the following statement will generate a compiler error:
t = st as MyType;
Now that you know to use as when possible, let’s discuss when you can’t use it. The as operator does not work on value types. This statement won’t compile:
object o = Factory.GetValue();
int i = o as int; // Does not compile.
(32) That’s because ints are value types and can never be null. What value of int should be stored in i if o is not an integer? Any value you pick might also be a valid integer. Therefore, as can’t be used. You’re stuck using the cast syntax. It’s actually a boxing/unboxing conversion (see Item 45):
object o = Factory.GetValue();
int i = 0;
try
{
i = (int)o;
}
catch (InvalidCastException)
{
i = 0;
}
Using exceptions as a flow control mechanism should strike you as a terrible practice. (See Item 47.) But you’re not stuck with the behaviors of casts. You can use the is statement to remove the chance of exceptions or conversions:
object o = Factory.GetValue();
int i = 0;
if (o is int)
i = (int)o;
If o is some other type that can be converted to an int, such as a double, the is operator returns false. The is operator always returns false for null arguments.
The is operator should be used only when you cannot convert the type using as. Otherwise, it’s simply redundant:
// correct, but redundant:
object o = Factory.GetObject();
MyType t = null;
if (o is MyType)
t = o as MyType;
The previous code is the same as if you had written the following:
// correct, but redundant:
object o = Factory.GetObject();
(33) MyType t = null;
if (o is MyType)
t = o as MyType;
That’s inefficient and redundant. If you’re about to convert a type using as, the is check is simply not necessary. Check the return from as against null; it’s simpler.
Now that you know the difference among is, as, and casts, which operator do you suppose the foreach loop uses? Foreach loops can operate on nongeneric IEnumerable sequences and have the type coercion built into the iteration. (You should prefer the type-safe generic versions whenever possible. The nongeneric version exists for historical purposes, and to support some late binding scenarios.)
public void UseCollection(IEnumerable theCollection)
{
foreach (MyType t in theCollection)
t.DoStuff( );
}
foreach uses a cast operation to perform conversions from an object to the type used in the loop. The code generated by the foreach statement roughly equates to this hand-coded version:
public void UseCollectionV2(IEnumerable theCollection)
{
IEnumerator it = theCollection.GetEnumerator();
while (it.MoveNext())
{
MyType t = (MyType)it.Current;
t.DoStuff();
}
}
foreach needs to use casts to support both value types and reference types. By choosing the cast operator, the foreach statement exhibits the same behavior, no matter what the destination type is. However, because a cast is used, foreach loops can cause an InvalidCastException to be thrown.
Because IEnumerator.Current returns a System.Object, which has no conversion operators, none is eligible for this test. A collection of SecondType objects cannot be used in the previous UseCollection() function because (34)
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.