88 lines
2.3 KiB
Plaintext
88 lines
2.3 KiB
Plaintext
== Why is this an issue?
|
|
|
|
https://en.wikipedia.org/wiki/Recursion[Recursion] is a technique used to define a problem in terms of the problem itself, usually in terms of a simpler version of the problem itself.
|
|
|
|
For example, the implementation of the generator for the n-th value of the https://en.wikipedia.org/wiki/Fibonacci_sequence[Fibonacci sequence] comes naturally from its mathematical definition, when recursion is used:
|
|
|
|
[source,vbnet]
|
|
----
|
|
Function NthFibonacciNumber(ByVal n As Integer) As Integer
|
|
If n <= 1 Then
|
|
Return 1
|
|
Else
|
|
Return NthFibonacciNumber(n - 1) + NthFibonacciNumber(n - 2)
|
|
End If
|
|
End Function
|
|
----
|
|
|
|
As opposed to:
|
|
|
|
[source,vbnet]
|
|
----
|
|
Function NthFibonacciNumber(ByVal n As Integer) As Integer
|
|
Dim previous As Integer = 0
|
|
Dim last As Integer = 1
|
|
|
|
For i = 0 To n - 1
|
|
Dim temp = previous
|
|
previous = last
|
|
last = last + temp
|
|
Next
|
|
|
|
Return last
|
|
End Function
|
|
----
|
|
|
|
Use of recursion is acceptable in methods, like the one above, where you can break out of it.
|
|
|
|
[source,vbnet]
|
|
----
|
|
Function NthFibonacciNumber(ByVal n As Integer) As Integer
|
|
If n <= 1 Then
|
|
Return 1 ' Base case: stop the recursion
|
|
}
|
|
----
|
|
|
|
It is also acceptable and makes sense in some type definitions:
|
|
|
|
[source,vbnet]
|
|
----
|
|
Class Box
|
|
Inherits IComparable(Of Box)
|
|
|
|
Public Function CompareTo(ByVal other As Box?) As Integer
|
|
' Compare the two Box instances...
|
|
End Function
|
|
End Class
|
|
----
|
|
|
|
With types, some invalid recursive definitions are caught by the compiler:
|
|
|
|
[source,vbnet]
|
|
----
|
|
Class C2(Of T) ' Error BC31447 C2(Of T) cannot reference itself in Inherits clause
|
|
Inherits C2(Of T)
|
|
End Class
|
|
|
|
Class C2(Of T)
|
|
Inherits C2(Of C2(Of T)) ' Error BC31447 C2(Of T) cannot reference itself in Inherits clause
|
|
End Class
|
|
----
|
|
|
|
In more complex scenarios, however, the code will compile but execution will result in a https://learn.microsoft.com/en-us/dotnet/api/system.typeloadexception[TypeLoadException] if you try to instantiate the class.
|
|
|
|
[source,vbnet]
|
|
----
|
|
Class C1(Of T)
|
|
End Class
|
|
|
|
Class C2(Of T) ' Noncompliant
|
|
Inherits C1(Of C2(Of C2(Of T)))
|
|
End Class
|
|
|
|
Dim c2 = New C2(Of Integer) ' This would result into a TypeLoadException
|
|
----
|
|
|
|
include::../resources.adoc[]
|
|
include::../rspecator.adoc[]
|