rspec/rules/S1944/vbnet/rule.adoc

92 lines
3.6 KiB
Plaintext
Raw Normal View History

2023-06-13 10:52:19 +02:00
== Why is this an issue?
2023-06-13 10:52:19 +02:00
A cast is an https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/implicit-and-explicit-conversions[explicit conversion], which is a way to tell the compiler the intent to convert from one type to another.
2023-06-13 10:52:19 +02:00
In Visual Basic, there are two explicit conversion operators:
2023-06-13 10:52:19 +02:00
[source,vbnet]
----
Public Sub Method(Value As Object)
Dim i As Integer
i = DirectCast(Value, Integer) ' Direct casting from object holding an integer type to Integer
i = CType(Value, Integer) ' Conversion from the underlying type to Integer
End Sub
----
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.
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/visual-basic/programming-guide/language-features/interfaces/[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/visual-basic/language-reference/operators/trycast-operator[`TryCast` operator].
When the conversion is not possible, the `TryCast` operator returns `Nothing` and will never raise an exception.
=== Code examples
==== Noncompliant code example
[source,vbnet,diff-id=1,diff-type=noncompliant]
----
Public Interface IMyInterface
End Interface
Public Class Implementer
Implements IMyInterface
End Class
Public Class AnotherClass
End Class
Module Program
Sub Main()
Dim Another As New AnotherClass
Dim x As IMyInterface = DirectCast(Another, IMyInterface) ' Noncompliant: InvalidCastException is being thrown
End Sub
End Module
----
==== Compliant solution
[source,vbnet,diff-id=1,diff-type=compliant]
----
Public Interface IMyInterface
2023-06-13 10:52:19 +02:00
End Interface
Public Class Implementer
Implements IMyInterface
End Class
Public Class AnotherClass
End Class
Module Program
Sub Main()
Dim Another As New AnotherClass
Dim x = TryCast(Another, IMyInterface) ' Compliant: but will always be Nothing
2023-06-13 10:52:19 +02:00
End Sub
End Module
----
== Resources
=== Documentation
* https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/type-conversions[Type Conversions in Visual Basic]
** https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/implicit-and-explicit-conversions[Implicit and Explicit Conversions in Visual Basic]
** https://learn.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/data-types/how-to-convert-an-object-to-another-type[How to: Convert an Object to Another Type in Visual Basic]
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/directcast-operator[`DirectCast` operator]
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/functions/ctype-function[`CType` function]
* https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/operators/trycast-operator[`TryCast` operator]
* 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[]