93 lines
3.4 KiB
Plaintext
Raw Permalink Normal View History

== Why is this an issue?
2023-06-13 10:52:19 +02:00
A cast is an https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions#explicit-conversions[explicit conversion], which is a way to tell the compiler the intent to convert from one type to another.
2020-06-30 12:47:33 +02:00
2023-06-13 10:52:19 +02:00
[source,csharp]
----
void Method(object value)
{
int i;
i = (int)value; // Casting (explicit conversion) from float to int
}
----
2020-06-30 12:47:33 +02:00
2023-06-13 10:52:19 +02:00
In most cases, the compiler will be able to catch invalid casts between incompatible value types or reference types.
2020-06-30 12:47:33 +02:00
2023-06-13 10:52:19 +02:00
However, the compiler will not be able to detect invalid casts to https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interface[interfaces].
=== What is the potential impact?
Invalid casts will lead to unexpected behaviors or runtime errors such as https://learn.microsoft.com/en-us/dotnet/api/system.invalidcastexception[InvalidCastException].
=== Exceptions
No issue is reported if the interface has no implementing class in the assembly.
== How to fix it
To prevent an `InvalidCastException` from raising during an explicit conversion, it is recommended to use the https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator[`as` operator].
When the conversion is not possible, the `as` operator returns `null` and will never raise an exception.
=== Code examples
==== Noncompliant code example
[source,csharp,diff-id=1,diff-type=noncompliant]
2020-06-30 12:47:33 +02:00
----
public interface IMyInterface
2020-06-30 12:47:33 +02:00
{ /* ... */ }
public class Implementer : IMyInterface
{ /* ... */ }
2023-06-13 10:52:19 +02:00
public class AnotherClass
2020-06-30 12:47:33 +02:00
{ /* ... */ }
public static class Program
{
public static void Main()
{
2023-06-13 10:52:19 +02:00
var another = new AnotherClass();
var x = (IMyInterface)another; // Noncompliant: InvalidCastException is being thrown
2020-06-30 12:47:33 +02:00
}
}
----
2023-06-13 10:52:19 +02:00
==== Compliant solution
2020-06-30 12:47:33 +02:00
2023-06-13 10:52:19 +02:00
[source,csharp,diff-id=1,diff-type=compliant]
2020-06-30 12:47:33 +02:00
----
public interface IMyInterface
2020-06-30 12:47:33 +02:00
{ /* ... */ }
public class Implementer : IMyInterface
{ /* ... */ }
2023-06-13 10:52:19 +02:00
public class AnotherClass
2020-06-30 12:47:33 +02:00
{ /* ... */ }
public static class Program
{
public static void Main()
{
2023-06-13 10:52:19 +02:00
var another = new AnotherClass();
var x = another as IMyInterface; // Compliant: but will always be null
2020-06-30 12:47:33 +02:00
}
}
----
2023-06-13 10:52:19 +02:00
== Resources
2023-06-13 10:52:19 +02:00
=== Documentation
2023-06-13 10:52:19 +02:00
* https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/casting-and-type-conversions#explicit-conversions[Casting and type conversions - Explicit conversion]
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast[Type-testing operators and cast expressions]
** https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#is-operator[`is` operator]
** https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#as-operator[`as` operator]
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#103-explicit-conversions[Conversions - Explicit conversions in C#]
** https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/conversions#1035-explicit-reference-conversions[Conversions - Explicit reference conversions in C#]
* CWE - https://cwe.mitre.org/data/definitions/588[CWE-588 - Attempt to Access Child of a Non-structure Pointer]
* CWE - https://cwe.mitre.org/data/definitions/704[CWE-704 - Incorrect Type Conversion or Cast]
2023-06-13 10:52:19 +02:00
include::../rspecator-dotnet.adoc[]