Skip to content

Commit

Permalink
fix warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
BillWagner committed Feb 4, 2025
1 parent 483cb89 commit a3857be
Show file tree
Hide file tree
Showing 23 changed files with 31 additions and 33 deletions.
4 changes: 2 additions & 2 deletions .openpublishing.redirection.csharp.json
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/as.md",
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator"
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#the-as-operator"
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/await.md",
Expand Down Expand Up @@ -1075,7 +1075,7 @@
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/typeof.md",
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#typeof-operator"
"redirect_url": "/dotnet/csharp/language-reference/operators/type-testing-and-cast#the-typeof-operator"
},
{
"source_path_from_root": "/docs/csharp/language-reference/keywords/types.md",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ helpviewer_keywords:
---
# How to safely cast by using pattern matching and the is and as operators

Because objects are polymorphic, it's possible for a variable of a base class type to hold a derived [type](../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](../functional/pattern-matching.md) statements that perform a cast conditionally only when it will succeed. C# also provides the [is](../../language-reference/operators/type-testing-and-cast.md#is-operator) and [as](../../language-reference/operators/type-testing-and-cast.md#as-operator) operators to test if a value is of a certain type.
Because objects are polymorphic, it's possible for a variable of a base class type to hold a derived [type](../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](../functional/pattern-matching.md) statements that perform a cast conditionally only when it will succeed. C# also provides the [is](../../language-reference/operators/type-testing-and-cast.md#the-is-operator) and [as](../../language-reference/operators/type-testing-and-cast.md#the-as-operator) operators to test if a value is of a certain type.

The following example shows how to use the pattern matching `is` statement:

:::code language="csharp" source="./snippets/safelycast/patternmatching/Program.cs" ID="PatternMatchingIs":::

The preceding sample demonstrates a few features of pattern matching syntax. The `if (a is Mammal m)` statement combines the test with an initialization assignment. The 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 can't access `m` later in the same method. The preceding example also shows how to use the [`as` operator](../../language-reference/operators/type-testing-and-cast.md#as-operator) to convert an object to a specified type.
The preceding sample demonstrates a few features of pattern matching syntax. The `if (a is Mammal m)` statement combines the test with an initialization assignment. The 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 can't access `m` later in the same method. The preceding example also shows how to use the [`as` operator](../../language-reference/operators/type-testing-and-cast.md#the-as-operator) to convert an object to a specified type.

You can also use the same syntax for testing if a [nullable value type](../../language-reference/builtin-types/nullable-value-types.md) has a value, as shown in the following example:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,17 +96,17 @@ The following example shows how to determine whether a <xref:System.Type?display

[!code-csharp-interactive[whether Type is nullable](snippets/shared/NullableValueTypes.cs#IsTypeNullable)]

As the example shows, you use the [typeof](../operators/type-testing-and-cast.md#typeof-operator) operator to create a <xref:System.Type?displayProperty=nameWithType> instance.
As the example shows, you use the [typeof](../operators/type-testing-and-cast.md#the-typeof-operator) operator to create a <xref:System.Type?displayProperty=nameWithType> instance.

If you want to determine whether an instance is of a nullable value type, don't use the <xref:System.Object.GetType%2A?displayProperty=nameWithType> method to get a <xref:System.Type> instance to be tested with the preceding code. When you call the <xref:System.Object.GetType%2A?displayProperty=nameWithType> method on an instance of a nullable value type, the instance is [boxed](#boxing-and-unboxing) to <xref:System.Object>. As boxing of a non-null instance of a nullable value type is equivalent to boxing of a value of the underlying type, <xref:System.Object.GetType%2A> returns a <xref:System.Type> instance that represents the underlying type of a nullable value type:

[!code-csharp-interactive[GetType example](snippets/shared/NullableValueTypes.cs#GetType)]

Also, don't use the [is](../operators/type-testing-and-cast.md#is-operator) operator to determine whether an instance is of a nullable value type. As the following example shows, you cannot distinguish types of a nullable value type instance and its underlying type instance with the `is` operator:
Also, don't use the [is](../operators/type-testing-and-cast.md#the-is-operator) operator to determine whether an instance is of a nullable value type. As the following example shows, you cannot distinguish types of a nullable value type instance and its underlying type instance with the `is` operator:

[!code-csharp-interactive[is operator example](snippets/shared/NullableValueTypes.cs#IsOperator)]

Instead use the <xref:System.Nullable.GetUnderlyingType%2A?displayProperty=nameWithType> from the first example and [typeof](../operators/type-testing-and-cast.md#typeof-operator) operator to check if an instance is of a nullable value type.
Instead use the <xref:System.Nullable.GetUnderlyingType%2A?displayProperty=nameWithType> from the first example and [typeof](../operators/type-testing-and-cast.md#the-typeof-operator) operator to check if an instance is of a nullable value type.

> [!NOTE]
> The methods described in this section are not applicable in the case of [nullable reference types](nullable-reference-types.md).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ These compiler errors indicate one of these problems in your code:

- The project doesn't reference the required assembly. To fix this error, [add a reference to the required assembly](../../../standard/assembly/index.md#add-a-reference-to-an-assembly).
- You misspelled the name of a type. Check the name of the type.
- You used a variable name where the name of a <xref:System.Type?displayProperty=nameWithType> was expected, such as in the [`typeof` operator](../operators/type-testing-and-cast.md#typeof-operator) or the [`is` operator](../operators/type-testing-and-cast.md#is-operator).
- You used a variable name where the name of a <xref:System.Type?displayProperty=nameWithType> was expected, such as in the [`typeof` operator](../operators/type-testing-and-cast.md#the-typeof-operator) or the [`is` operator](../operators/type-testing-and-cast.md#the-is-operator).
- You used the [global scope operator, (`::`)](../operators/namespace-alias-qualifier.md) when the type isn't in the global namespace.

## Type forwarding
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/compiler-messages/cs0039.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ms.assetid: f9fcb1c5-4ea4-41f3-826e-9ab0ac43dd3e

Cannot convert type 'type1' to 'type2' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

A conversion with the [as](../operators/type-testing-and-cast.md#as-operator) operator is allowed by inheritance, reference conversions, and boxing conversions.
A conversion with the [as](../operators/type-testing-and-cast.md#the-as-operator) operator is allowed by inheritance, reference conversions, and boxing conversions.

## Example

Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/compiler-messages/cs0413.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ ms.assetid: a01bd1ec-015b-433b-be55-b91db268d6a5

The type parameter 'type parameter' cannot be used with the 'as' operator because it does not have a class type constraint nor a 'class' constraint

This error occurs if a generic type uses the [as](../operators/type-testing-and-cast.md#as-operator) operator, but that generic type does not have a class type constraint. The `as` operator is only allowed with reference and nullable value types, so the type parameter must be constrained to guarantee that it is not a value type. To avoid this error, use a class type constraint or a reference type constraint.
This error occurs if a generic type uses the [as](../operators/type-testing-and-cast.md#the-as-operator) operator, but that generic type does not have a class type constraint. The `as` operator is only allowed with reference and nullable value types, so the type parameter must be constrained to guarantee that it is not a value type. To avoid this error, use a class type constraint or a reference type constraint.

This is because the `as` operator could return `null`, which is not a possible value for a value type, and the type parameter must be treated as a value type unless it is a class type constraint or a reference type constraint.

Expand Down
4 changes: 2 additions & 2 deletions docs/csharp/language-reference/keywords/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The first table in this article lists keywords that are reserved identifiers in
:::row:::
:::column:::
[`abstract`](abstract.md)
[`as`](../operators/type-testing-and-cast.md#as-operator)
[`as`](../operators/type-testing-and-cast.md#the-as-operator)
[`base`](base.md)
[`bool`](../builtin-types/bool.md)
[`break`](../statements/jump-statements.md#the-break-statement)
Expand Down Expand Up @@ -91,7 +91,7 @@ The first table in this article lists keywords that are reserved identifiers in
[`throw`](../statements/exception-handling-statements.md#the-throw-statement)
[`true`](../builtin-types/bool.md)
[`try`](../statements/exception-handling-statements.md#the-try-statement)
[`typeof`](../operators/type-testing-and-cast.md#typeof-operator)
[`typeof`](../operators/type-testing-and-cast.md#the-typeof-operator)
[`uint`](../builtin-types/integral-numeric-types.md)
[`ulong`](../builtin-types/integral-numeric-types.md)
[`unchecked`](../statements/checked-and-unchecked.md)
Expand Down
4 changes: 2 additions & 2 deletions docs/csharp/language-reference/operators/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ The following table lists the C# operators starting with the highest precedence

| Operators | Category or name |
| --------- | ---------------- |
| [x.y](member-access-operators.md#member-access-expression-), [f(x)](member-access-operators.md#invocation-expression-), [a&#91;i&#93;](member-access-operators.md#indexer-operator-), [`x?.y`](member-access-operators.md#null-conditional-operators--and-), [`x?[y]`](member-access-operators.md#null-conditional-operators--and-), [x++](arithmetic-operators.md#increment-operator-), [x--](arithmetic-operators.md#decrement-operator---), [x!](null-forgiving.md), [new](new-operator.md), [typeof](type-testing-and-cast.md#typeof-operator), [checked](../statements/checked-and-unchecked.md), [unchecked](../statements/checked-and-unchecked.md), [default](default.md), [nameof](nameof.md), [delegate](delegate-operator.md), [sizeof](sizeof.md), [stackalloc](stackalloc.md), [x->y](pointer-related-operators.md#pointer-member-access-operator--) | Primary |
| [x.y](member-access-operators.md#member-access-expression-), [f(x)](member-access-operators.md#invocation-expression-), [a&#91;i&#93;](member-access-operators.md#indexer-operator-), [`x?.y`](member-access-operators.md#null-conditional-operators--and-), [`x?[y]`](member-access-operators.md#null-conditional-operators--and-), [x++](arithmetic-operators.md#increment-operator-), [x--](arithmetic-operators.md#decrement-operator---), [x!](null-forgiving.md), [new](new-operator.md), [typeof](type-testing-and-cast.md#the-typeof-operator), [checked](../statements/checked-and-unchecked.md), [unchecked](../statements/checked-and-unchecked.md), [default](default.md), [nameof](nameof.md), [delegate](delegate-operator.md), [sizeof](sizeof.md), [stackalloc](stackalloc.md), [x->y](pointer-related-operators.md#pointer-member-access-operator--) | Primary |
| [+x](arithmetic-operators.md#unary-plus-and-minus-operators), [-x](arithmetic-operators.md#unary-plus-and-minus-operators), [\!x](boolean-logical-operators.md#logical-negation-operator-), [~x](bitwise-and-shift-operators.md#bitwise-complement-operator-), [++x](arithmetic-operators.md#increment-operator-), [--x](arithmetic-operators.md#decrement-operator---), [^x](member-access-operators.md#index-from-end-operator-), [(T)x](type-testing-and-cast.md#cast-expression), [await](await.md), [&x](pointer-related-operators.md#address-of-operator-), [*x](pointer-related-operators.md#pointer-indirection-operator-), [true and false](true-false-operators.md) | Unary |
| [x..y](member-access-operators.md#range-operator-) | Range |
| [switch](switch-expression.md), [with](with-expression.md) | `switch` and `with` expressions |
| [x * y](arithmetic-operators.md#multiplication-operator-), [x / y](arithmetic-operators.md#division-operator-), [x % y](arithmetic-operators.md#remainder-operator-) | Multiplicative|
| [x + y](arithmetic-operators.md#addition-operator-), [x – y](arithmetic-operators.md#subtraction-operator--) | Additive |
| [x \<\< y](bitwise-and-shift-operators.md#left-shift-operator-), [x >> y](bitwise-and-shift-operators.md#right-shift-operator-), [x >>> y](bitwise-and-shift-operators.md#unsigned-right-shift-operator-) | Shift |
| [x \< y](comparison-operators.md#less-than-operator-), [x > y](comparison-operators.md#greater-than-operator-), [x \<= y](comparison-operators.md#less-than-or-equal-operator-), [x >= y](comparison-operators.md#greater-than-or-equal-operator-), [is](type-testing-and-cast.md#is-operator), [as](type-testing-and-cast.md#as-operator) | Relational and type-testing |
| [x \< y](comparison-operators.md#less-than-operator-), [x > y](comparison-operators.md#greater-than-operator-), [x \<= y](comparison-operators.md#less-than-or-equal-operator-), [x >= y](comparison-operators.md#greater-than-or-equal-operator-), [is](type-testing-and-cast.md#the-is-operator), [as](type-testing-and-cast.md#the-as-operator) | Relational and type-testing |
| [x == y](equality-operators.md#equality-operator-), [x != y](equality-operators.md#inequality-operator-) | Equality |
| `x & y` | [Boolean logical AND](boolean-logical-operators.md#logical-and-operator-) or [bitwise logical AND](bitwise-and-shift-operators.md#logical-and-operator-) |
| `x ^ y` | [Boolean logical XOR](boolean-logical-operators.md#logical-exclusive-or-operator-) or [bitwise logical XOR](bitwise-and-shift-operators.md#logical-exclusive-or-operator-) |
Expand Down
2 changes: 1 addition & 1 deletion docs/csharp/language-reference/operators/is.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ helpviewer_keywords:
---
# is operator (C# reference)

The `is` operator checks if the result of an expression is compatible with a given type. For information about the type-testing `is` operator, see the [is operator](type-testing-and-cast.md#is-operator) section of the [Type-testing and cast operators](type-testing-and-cast.md) article. You can also use the `is` operator to match an expression against a pattern, as the following example shows:
The `is` operator checks if the result of an expression is compatible with a given type. For information about the type-testing `is` operator, see the [is operator](type-testing-and-cast.md#the-is-operator) section of the [Type-testing and cast operators](type-testing-and-cast.md) article. You can also use the `is` operator to match an expression against a pattern, as the following example shows:

:::code language="csharp" source="snippets/shared/IsOperator.cs" id="IntroExample":::

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The following table shows the operators that can't be overloaded:
|[<code>a&#91;i&#93;</code>](member-access-operators.md#indexer-operator-), [`a?[i]`](member-access-operators.md#null-conditional-operators--and-)|Define an [indexer](../../programming-guide/indexers/index.md).|
|[`(T)x`](type-testing-and-cast.md#cast-expression)|Define custom type conversions that can be performed by a cast expression. For more information, see [User-defined conversion operators](user-defined-conversion-operators.md).|
|[`+=`](arithmetic-operators.md#compound-assignment), [`-=`](arithmetic-operators.md#compound-assignment), [`*=`](arithmetic-operators.md#compound-assignment), [`/=`](arithmetic-operators.md#compound-assignment), [`%=`](arithmetic-operators.md#compound-assignment), [`&=`](boolean-logical-operators.md#compound-assignment), [<code>&#124;=</code>](boolean-logical-operators.md#compound-assignment), [`^=`](boolean-logical-operators.md#compound-assignment), [`<<=`](bitwise-and-shift-operators.md#compound-assignment), [`>>=`](bitwise-and-shift-operators.md#compound-assignment), [`>>>=`](bitwise-and-shift-operators.md#compound-assignment)|Overload the corresponding binary operator. For example, when you overload the binary `+` operator, `+=` is implicitly overloaded.|
|[`^x`](member-access-operators.md#index-from-end-operator-), [`x = y`](assignment-operator.md), [`x.y`](member-access-operators.md#member-access-expression-), [`x?.y`](member-access-operators.md#null-conditional-operators--and-), [`c ? t : f`](conditional-operator.md), [`x ?? y`](null-coalescing-operator.md), [`??= y`](null-coalescing-operator.md),<br />[`x..y`](member-access-operators.md#range-operator-), [`x->y`](pointer-related-operators.md#pointer-member-access-operator--), [`=>`](lambda-operator.md), [`f(x)`](member-access-operators.md#invocation-expression-), [`as`](type-testing-and-cast.md#as-operator), [`await`](await.md), [`checked`](../statements/checked-and-unchecked.md), [`unchecked`](../statements/checked-and-unchecked.md), [`default`](default.md), [`delegate`](delegate-operator.md), [`is`](type-testing-and-cast.md#is-operator), [`nameof`](nameof.md), [`new`](new-operator.md), <br />[`sizeof`](sizeof.md), [`stackalloc`](stackalloc.md), [`switch`](switch-expression.md), [`typeof`](type-testing-and-cast.md#typeof-operator), [`with`](with-expression.md)|None.|
|[`^x`](member-access-operators.md#index-from-end-operator-), [`x = y`](assignment-operator.md), [`x.y`](member-access-operators.md#member-access-expression-), [`x?.y`](member-access-operators.md#null-conditional-operators--and-), [`c ? t : f`](conditional-operator.md), [`x ?? y`](null-coalescing-operator.md), [`??= y`](null-coalescing-operator.md),<br />[`x..y`](member-access-operators.md#range-operator-), [`x->y`](pointer-related-operators.md#pointer-member-access-operator--), [`=>`](lambda-operator.md), [`f(x)`](member-access-operators.md#invocation-expression-), [`as`](type-testing-and-cast.md#the-as-operator), [`await`](await.md), [`checked`](../statements/checked-and-unchecked.md), [`unchecked`](../statements/checked-and-unchecked.md), [`default`](default.md), [`delegate`](delegate-operator.md), [`is`](type-testing-and-cast.md#the-is-operator), [`nameof`](nameof.md), [`new`](new-operator.md), <br />[`sizeof`](sizeof.md), [`stackalloc`](stackalloc.md), [`switch`](switch-expression.md), [`typeof`](type-testing-and-cast.md#the-typeof-operator), [`with`](with-expression.md)|None.|

## C# language specification

Expand Down
Loading

0 comments on commit a3857be

Please sign in to comment.