|
|
@@ -10,7 +10,7 @@ Casting only works for types that inherit the base type that you want to unbox f |
|
|
|
`IUser` cannot be cast to `IMessage`. |
|
|
|
|
|
|
|
> [!NOTE] |
|
|
|
> Interfaces CAN be cast to other interfaces, as long as they inherit eachother. |
|
|
|
> Interfaces **can** be cast to other interfaces, as long as they inherit eachother. |
|
|
|
> The same goes for reverse casting. As long as some entity can be simplified into what it inherits, your cast will pass. |
|
|
|
|
|
|
|
## Boxing |
|
|
@@ -25,17 +25,17 @@ Through casting, we can **unbox** this type, and access the properties that were |
|
|
|
Unboxing is the most direct way to access the real definition of an object. |
|
|
|
If we want to return a type from its interface, we can unbox it directly. |
|
|
|
|
|
|
|
[!code-csharp[Unboxing](images/unboxing.cs)] |
|
|
|
[!code-csharp[Unboxing](samples/unboxing.cs)] |
|
|
|
|
|
|
|
## Regular casting |
|
|
|
|
|
|
|
In 'regular' casting, we use the ` as ` keyword to assign the given type to the object. |
|
|
|
In 'regular' casting, we use the `as` keyword to assign the given type to the object. |
|
|
|
If the boxed type can indeed be cast into given type, |
|
|
|
it will become said type, and its properties can be accessed. |
|
|
|
[!code-csharp[Casting](images/casting.cs)] |
|
|
|
[!code-csharp[Casting](samples/casting.cs)] |
|
|
|
|
|
|
|
> [!WARNING] |
|
|
|
> If the type you're casting to is null, a ` NullReferenceException ` will be thrown when its called. |
|
|
|
> If the type you're casting to is null, a `NullReferenceException` will be thrown when its called. |
|
|
|
> This makes safety casting much more interesting to use, as it prevents this exception from being thrown. |
|
|
|
|
|
|
|
## Safety casting |
|
|
@@ -48,21 +48,21 @@ There are 3 different ways to safety cast an object: |
|
|
|
|
|
|
|
To safety cast an object, all we need to do is check if it is of the member type in a statement. |
|
|
|
If this check fails, it will continue below, making sure we don't try to access null. |
|
|
|
[!code-csharp[Base](images/safety-cast.cs)] |
|
|
|
[!code-csharp[Base](samples/safety-cast.cs)] |
|
|
|
|
|
|
|
### Object declaration: |
|
|
|
|
|
|
|
Here we declare the object we are casting to, |
|
|
|
making it so that you can immediately work with its properties without reassigning through regular casting. |
|
|
|
[!code-csharp[Declare](images/safety-cast-var.cs)] |
|
|
|
[!code-csharp[Declare](samples/safety-cast-var.cs)] |
|
|
|
|
|
|
|
### Reverse passage: |
|
|
|
|
|
|
|
In previous examples, we want to let code continue running after the check, or if the check fails. |
|
|
|
In this example, the cast will return the entire method (ignoring the latter) upon failure, |
|
|
|
and declare the variable for further use into the method: |
|
|
|
[!code-csharp[Pass](images/safety-cast-pass.cs)] |
|
|
|
[!code-csharp[Pass](samples/safety-cast-pass.cs)] |
|
|
|
|
|
|
|
> [!NOTE] |
|
|
|
> Usage of ` is `, ` not ` and ` as ` is required in cast assignment and/or type checks. ==, != and = are invalid assignment, |
|
|
|
> Usage of `is`, `not` and `as` is required in cast assignment and/or type checks. `==`, `!=` and `=` are invalid assignment, |
|
|
|
> as these operators only apply to initialized objects and not their types. |