Использование методов расширения из конструктора объекта, где «Me» - целевой объект ByRef. - PullRequest
4 голосов
/ 09 февраля 2010

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

Public Module Extensions
    <Extension()> _
    Public Sub Initialize(ByRef Target as SomeClass, ByVal SomeParam as Something )
        ...
        Target  = SomethingElse
    end Sub
End Module

Class SomeClass
...

    sub New(ByVal SomeParam as Something )
       Me.Initialize(SomeParam)
    end sub

    sub New()

    end sub

End Class


'Case 1: Doesnt Work...why????:

    Dim foo as new SomeClass(SomeParam) 'foo remains uninitialized


'Case 2: Does Work:
    Dim foo as new SomeClass()
    foo.Initialize(SomeParam) 'foo is initialized

Вопрос: Почему в случае 1 не удалось инициализировать объект должным образом?

1 Ответ

4 голосов
/ 09 февраля 2010

Проблема здесь в том, что VB.Net поддерживает несколько способов использования параметров ByRef. Я сделал подробное объяснение типов в недавней записи в блоге

Здесь происходит то, что Me не является присваиваемым значением. Поэтому вместо передачи Me в качестве параметра byRef компилятор VB вместо этого передаст временный. Это широко известно как «Copy Back ByRef». Эффективно генерирует следующий код

Dim temp = Me
Initialize(temp, SomeParam)

Нет способа обойти это в случае Me, потому что он не может быть назначен. В случае локальной переменной foo это работает, как и ожидалось, поскольку foo является допустимым значением ByRef.

...