Почему в предупреждении VB.NET о «отсутствующем возвращаемом значении» специально исключены «не встроенные типы значений»? - PullRequest
0 голосов
/ 29 ноября 2018

Рассмотрим следующий пример кода:

Function f1() As Object     ' yields warning BC42353
End Function

Function f2() As Int32      ' yields warning BC42353
End Function

Function f3() As DateTime   ' yields warning BC42353
End Function

Function f4() As Guid       ' no warning
End Function

и следующие настройки проекта:

project settings

По-видимому, VB.NETразличает следующие три категории типов:

  1. ссылочные типы [Пример f1],
  2. «встроенные» типы значений (некоторые явно недокументированные подкатегории типов значений см. Что такое внутренний тип значения? ) [Примеры f2 и f3],
  3. «не внутренние» типы значений [Пример f4],

и предложения «отсутствуют»возвращаемое значение "предупреждения для 1 + 2, но не для 3 (такая опция компилятора недоступна).

Что такого особенного в" не внутренних типах значений ", что разработчики языка решили пропустить этофункция для этой категории типов?

(я подозреваю, что это было преднамеренное решение, так как (я полагаю) было бы проще реализовать функцию для всех типов значений, чем проверять некоторые жесткиесначала закодированный «внутренний» белый список.)

1 Ответ

0 голосов
/ 07 декабря 2018

Учитывая исходный код исходного кода анализа потока компилятора Roslyn VB и особенно в потоке данных, который можно найти здесь в строке 1232 запускает подпрограмму, которая решает, следует ли генерировать это предупреждение.Обратите внимание, что я предполагаю, что на основании различных поисков, которые я выполнил в репозитории.

Оператор if начинается в строке 1250, которая выглядит следующим образом:

                If type.IsIntrinsicValueType Then


                    Select Case MethodSymbol.MethodKind
                        Case MethodKind.Conversion, MethodKind.UserDefinedOperator
                            warning = ERRID.WRN_DefAsgNoRetValOpVal1
                        Case MethodKind.PropertyGet
                            warning = ERRID.WRN_DefAsgNoRetValPropVal1
                        Case Else
                            Debug.Assert(MethodSymbol.MethodKind = MethodKind.Ordinary OrElse MethodSymbol.MethodKind = MethodKind.LambdaMethod)
                            warning = ERRID.WRN_DefAsgNoRetValFuncVal1
                    End Select


                ElseIf type.IsReferenceType Then


                    Select Case MethodSymbol.MethodKind
                        Case MethodKind.Conversion, MethodKind.UserDefinedOperator
                            warning = ERRID.WRN_DefAsgNoRetValOpRef1
                        Case MethodKind.PropertyGet
                            warning = ERRID.WRN_DefAsgNoRetValPropRef1
                        Case Else
                            Debug.Assert(MethodSymbol.MethodKind = MethodKind.Ordinary OrElse MethodSymbol.MethodKind = MethodKind.LambdaMethod)
                            warning = ERRID.WRN_DefAsgNoRetValFuncRef1
                    End Select


                ElseIf type.TypeKind = TypeKind.TypeParameter Then
                    ' IsReferenceType was false, so this type parameter was not known to be a reference type.
                    ' Following past practice, no warning is given in this case.


                Else
                    Debug.Assert(type.IsValueType)
                    Select Case MethodSymbol.MethodKind
                        Case MethodKind.Conversion, MethodKind.UserDefinedOperator
                            ' no warning is given in this case.
                        Case MethodKind.PropertyGet
                            warning = ERRID.WRN_DefAsgNoRetValPropRef1
                        Case MethodKind.EventAdd
                            ' In Dev11, there wasn't time to change the syntax of AddHandler to allow the user
                            ' to specify a return type (necessarily, EventRegistrationToken) for WinRT events.
                            ' DevDiv #376690 reflects the fact that this leads to an incredibly confusing user
                            ' experience if nothing is return: no diagnostics are reported, but RemoveHandler
                            ' statements will silently fail.  To prompt the user, (1) warn if there is no
                            ' explicit return, and (2) modify the error message to say "AddHandler As 
                            ' EventRegistrationToken" to hint at the nature of the problem.
                            ' Update: Dev11 just mangles an existing error message, but we'll introduce a new, 
                            ' clearer, one.


                            warning = ERRID.WRN_DefAsgNoRetValWinRtEventVal1
                            localName = MethodSymbol.AssociatedSymbol.Name
                        Case Else
                            warning = ERRID.WRN_DefAsgNoRetValFuncRef1
                    End Select
                End If

Как видно из единственного условияпредупреждение не генерируется, если свойство TypeKind равно TypeParameter.Я действительно не знаю больше о таких типах, но я предполагаю, что есть некоторые классы / типы в .NET Framework (GUID должен быть одним из них), которые ведут себя таким образом.

Это не такпохоже, что это решение вообще, а не спроектированное поведение компилятора в определенных типах.Однако из кода видно, что добавить предупреждение в зависимости от типа метода (в данном случае функции) не так сложно, независимо от возвращаемого типа, что, на мой взгляд, лучше всего сделать.

Надеюсь, это поможет.

...