Skip to content

rework the how-to for casting and pattern matching #7520

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .openpublishing.redirection.json
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,10 @@
"source_path":"docs/csharp/programming-guide/nullable-types/how-to-safely-cast-from-bool-to-bool.md",
"redirect_url":"/dotnet/csharp/programming-guide/nullable-types/using-nullable-types"
},
{
"source_path":"docs/csharp/programming-guide/types/how-to-safely-cast-using-as-and-is-operators.md",
"redirect_url":"/dotnet/csharp/how-to/safely-cast-using-pattern-matching-is-and-as-operators"
},
{
"source_path":"docs/standard/asynchronous-programming-patterns/multithreaded-programming-with-the-event-based-asynchronous-pattern.md",
"redirect_url":"/dotnet/standard/asynchronous-programming-patterns/event-based-asynchronous-pattern-eap"
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ You may need to convert an object to a different type.
- [Convert a string to a `DateTime`](../../standard/base-types/parsing-datetime.md).
- [Convert a byte array to an int](../programming-guide/types/how-to-convert-a-byte-array-to-an-int.md).
- [Convert a string to a number](../programming-guide/types/how-to-convert-a-string-to-a-number.md).
- [Use `as` and `is` to safely cast to a different type](../programming-guide/types/how-to-safely-cast-by-using-as-and-is-operators.md).
- [Use pattern matching, the `as` and `is` operators to safely cast to a different type](../how-to/safely-cast-using-pattern-matching-is-and-as-operators.md).
- [Define conversion operators for `struct` types](../programming-guide/statements-expressions-operators/how-to-implement-user-defined-conversions-between-structs.md).
- [Determine if a type is a nullable value type](../programming-guide/nullable-types/how-to-identify-a-nullable-type.md).
- [Convert between nullable and non-nullable value types](../programming-guide/nullable-types/using-nullable-types.md#conversion-from-a-nullable-type-to-an-underlying-type).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: "How to: safely cast by using pattern matching and the is and as operators"
description: Learn to use pattern matching techniques to safely cast variables to a different type. You can use pattern matching as well as the is and as operators to safely convert types.
ms.date: 09/05/2018
helpviewer_keywords:
- "cast operators [C#], as and is operators"
- "as operator [C#]"
- "is operator [C#]"
---
# How to: safely cast by using pattern matching is and as operators

Because objects are polymorphic, it's possible for a variable of a base class type to hold a derived [type](../programming-guide/types/index.md). To access the derived type's instance members, it's necessary to [cast](../programming-guide/types/casting-and-type-conversions.md) the value back to the derived type. However, a cast creates the risk of throwing an <xref:System.InvalidCastException>. C# provides [pattern matching](../pattern-matching.md) statements that perform a cast conditionally only when it will succeed. C# also provides the [is](../language-reference/keywords/is.md) and [as](../language-reference/keywords/as.md) operators to test if a value is of a certain type.

[!INCLUDE[interactive-note](~/includes/csharp-interactive-note.md)]

The following code demonstrates the pattern matching `is` statement. It contains methods that test a method argument to determine if it is one of a possible set of derived types:

[!code-csharp-interactive[Pattern matching is statement](../../../samples/snippets/csharp/how-to/safelycast/patternmatching/Program.cs#PatternMatchingIs)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the namespace statement isn't supported in the repl.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked at the source snippet, and it seemed fine. After updating based on all the other feedback, the namespace statement is not in the interactive sample. The sample code snippets are correct. (Verified on the review site with the new build).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes -- no namespace statement.


The preceding sample demonstrates a few features of pattern matching syntax. The `if (a is Mammal m)` and `if (o is Mammal m)` statements combine the test with an initialization assignment. TThe assignment occurs only when the test succeeds. The variable `m` is only in scope in the embedded `if` statement where it has been assigned. You cannot access `m` later in the same method. Try it in the interactive window.

You can also use the same syntax for testing if a [nullable type](../programming-guide/nullable-types/index.md) has a value, as shown in the following sample code:

[!code-csharp-interactive[Pattern matching with nullable types](../../../samples/snippets/csharp/how-to/safelycast/nullablepatternmatching/Program.cs#PatternMatchingNullable)]

The preceding sample demonstrates other features of pattern matching to use with conversions. You can test a variable for the null pattern by checking specifically for the `null` value. When the runtime value of the variable is `null`, an `is` statement checking for a type always returns `false`. The pattern matching `is` statement doesn't allow a nullable value type, such as `int?` or `Nullable<int>`, but you can test for any other value type.

The preceding sample also shows how you use the pattern matching `is` expression in a `switch` statement where the variable may be one of many different types.

If you want to test if a variable is a given type, but not assign it to a new variable, you can use the `is` and `as` operators for reference types and nullable types. The following code shows how to use the `is` and `as` statements that were part of the C# language before pattern matching was introduced to test if a variable is of a given type:

[!code-csharp-interactive[testing variable types with the is and as statements](../../../samples/snippets/csharp/how-to/safelycast/asandis/Program.cs#IsAndAs)]

As you can see by comparing this code with the pattern matching code, the pattern matching syntax provides more robust features by combining the test and the assignment in a single statement. Use the pattern matching syntax whenever possible.

You can try these samples by looking at the code in our [GitHub repository](https://github.com/dotnet/samples/tree/master/snippets/csharp/how-to/safelycast). Or you can download the samples [as a zip file](https://github.com/dotnet/samples/raw/master/snippets/csharp/how-to/safelycast.zip).
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/keywords/dynamic.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ For more information and examples, see [Using Type dynamic](../../../csharp/prog
- [is](../../../csharp/language-reference/keywords/is.md)
- [as](../../../csharp/language-reference/keywords/as.md)
- [typeof](../../../csharp/language-reference/keywords/typeof.md)
- [How to: Safely Cast by Using as and is Operators](../../../csharp/programming-guide/types/how-to-safely-cast-by-using-as-and-is-operators.md)
- [How to: Safely cast Using pattern matching, as, and is Operators](../../how-to/safely-cast-using-pattern-matching-is-and-as-operators.md)
- [Walkthrough: Creating and Using Dynamic Objects](../../../csharp/programming-guide/types/walkthrough-creating-and-using-dynamic-objects.md)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Giraffe g2 = (Giraffe) a;

[!code-csharp[csProgGuideTypes#41](../../../csharp/programming-guide/nullable-types/codesnippet/CSharp/casting-and-type-conversions_3.cs)]

C# provides the [is](../../../csharp/language-reference/keywords/is.md) and [as](../../../csharp/language-reference/keywords/as.md) operators to enable you to test for compatibility before actually performing a cast. For more information, see [How to: Safely Cast by Using as and is Operators](../../../csharp/programming-guide/types/how-to-safely-cast-by-using-as-and-is-operators.md).
C# provides the [is](../../../csharp/language-reference/keywords/is.md) and [as](../../../csharp/language-reference/keywords/as.md) operators to enable you to test for compatibility before actually performing a cast. For more information, see [How to: Safely cast using pattern matching, as and is Operators](../../how-to/safely-cast-using-pattern-matching-is-and-as-operators.md).

## C# Language Specification
[!INCLUDE[CSharplangspec](~/includes/csharplangspec-md.md)]
Expand Down

This file was deleted.

1 change: 0 additions & 1 deletion docs/csharp/programming-guide/types/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
## [Boxing and Unboxing](boxing-and-unboxing.md)
## [Using Type dynamic](using-type-dynamic.md)
### [Walkthrough: Creating and Using Dynamic Objects (C# and Visual Basic)](walkthrough-creating-and-using-dynamic-objects.md)
## [How to: Safely Cast by Using as and is Operators](how-to-safely-cast-by-using-as-and-is-operators.md)
## [How to: Convert a byte Array to an int](how-to-convert-a-byte-array-to-an-int.md)
## [How to: Convert a String to a Number](how-to-convert-a-string-to-a-number.md)
## [How to: Convert Between Hexadecimal Strings and Numeric Types](how-to-convert-between-hexadecimal-strings-and-numeric-types.md)
1 change: 1 addition & 0 deletions docs/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@
### [Search strings](csharp/how-to/search-strings.md)
### [Modify string contents](csharp/how-to/modify-string-contents.md)
### [Compare strings](csharp/how-to/compare-strings.md)
### [Safely cast using pattern matching, is and as operators](csharp/how-to/safely-cast-using-pattern-matching-is-and-as-operators.md)
<!-- End of C# Concepts section -->
## [The .NET Compiler Platform SDK (Roslyn APIs)](csharp/roslyn-sdk/)
## [C# Programming Guide](csharp/programming-guide/)
Expand Down