93 lines
3.4 KiB
Plaintext
93 lines
3.4 KiB
Plaintext
== Why is this an issue?
|
|
|
|
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.
|
|
|
|
[source,csharp]
|
|
----
|
|
void Method(object value)
|
|
{
|
|
int i;
|
|
i = (int)value; // Casting (explicit conversion) from float to int
|
|
}
|
|
----
|
|
|
|
In most cases, the compiler will be able to catch invalid casts between incompatible value types or reference types.
|
|
|
|
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]
|
|
----
|
|
public interface IMyInterface
|
|
{ /* ... */ }
|
|
|
|
public class Implementer : IMyInterface
|
|
{ /* ... */ }
|
|
|
|
public class AnotherClass
|
|
{ /* ... */ }
|
|
|
|
public static class Program
|
|
{
|
|
public static void Main()
|
|
{
|
|
var another = new AnotherClass();
|
|
var x = (IMyInterface)another; // Noncompliant: InvalidCastException is being thrown
|
|
}
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,csharp,diff-id=1,diff-type=compliant]
|
|
----
|
|
public interface IMyInterface
|
|
{ /* ... */ }
|
|
|
|
public class Implementer : IMyInterface
|
|
{ /* ... */ }
|
|
|
|
public class AnotherClass
|
|
{ /* ... */ }
|
|
|
|
public static class Program
|
|
{
|
|
public static void Main()
|
|
{
|
|
var another = new AnotherClass();
|
|
var x = another as IMyInterface; // Compliant: but will always be null
|
|
}
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* 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]
|
|
|
|
include::../rspecator-dotnet.adoc[]
|