Как получить доступ к самому объекту в With End With

Некоторый код, чтобы проиллюстрировать мой вопрос:

With Test.AnObject

    .Something = 1337
    .AnotherThing = "Hello"

    ''// why can't I do this to pass the object itself:
    Test2.Subroutine(.)
    ''// ... and is there an equivalent, other than repeating the object in With?

End With

person Community    schedule 20.07.2009    source источник


Ответы (4)


Невозможно сослаться на объект, указанный в операторе With, кроме повторения имени самого объекта.

РЕДАКТИРОВАТЬ

Если вы действительно хотите, вы можете изменить свой объект, чтобы вернуть ссылку на себя

Public Function Self() as TypeOfAnObject
    Return Me
End Get

Затем вы можете использовать следующий код

With Test.AnObject
    Test2.Subroutine(.Self())
End With

Наконец, если вы не можете изменить код объекта, вы можете (но не обязательно должны) сделать то же самое с помощью метод расширения. Одно универсальное решение:

' Define in a Module
<Extension()>
Public Function Self(Of T)(target As T) As T
    Return target
End Function

называется так:

Test2.Subroutine(.Self())

or

With 1
   a = .Self() + 2 ' a now equals 3
End With
person Patrick McDonald    schedule 20.07.2009
comment
Если ваш класс когда-либо будет сериализован, вам нужно использовать функцию, а не свойство только для чтения! Какие-либо особые преимущества для собственности здесь в другом случае? - person Adam; 26.05.2017
comment
Обсуждение свойств и методов см. в разделе stackoverflow.com/questions/601621/properties-vs-methods. - person Patrick McDonald; 28.05.2017
comment
В частности: В общем, методы представляют действия, а свойства представляют данные. Свойства предназначены для использования как поля, а это означает, что свойства не должны быть сложными в вычислительном отношении или создавать побочные эффекты. Если это не нарушает следующие рекомендации, рассмотрите возможность использования свойства, а не метода, поскольку менее опытные разработчики находят свойства более простыми в использовании. - person Patrick McDonald; 28.05.2017
comment
Также обратите внимание, что этот ответ немного хакерский, и, вероятно, было бы предпочтительнее сохранить ссылку на цель With в локальной переменной и вместо этого ссылаться на нее. - person Patrick McDonald; 28.05.2017
comment
Да, тогда вам вообще не нужен With. Я согласен с тем, что концептуально это лучше подходит как свойство, чем как функция. Но как свойство оно вызывает бесконечную рекурсию, если вы попытаетесь сериализовать класс, поэтому я получил функцию. - person Adam; 28.05.2017
comment
Вы меня убедили! - person Patrick McDonald; 29.05.2017
comment
@PatrickMcDonald, спасибо, сэр, вы спасли мой день и немного волос :) - person Zakir_SZH; 18.10.2019

Подозреваю, что вам придется повториться. Если выражение (для получения объекта) дорогое, то, возможно, сначала поместите его в переменную и либо используйте эту переменную в With, либо полностью удалите With:

tmp = Test.AnObject;
tmp.Something = 1337;
...
Test2.Subroutine(tmp);
person Marc Gravell    schedule 20.07.2009

Как говорили другие, вам придется писать

Test2.Subroutine(Test.AnObject)

Это хороший пример того, почему стоит быть немного осторожным с конструкцией With в VB.Net. Я считаю, что для того, чтобы его вообще стоило использовать, вам действительно нужно установить более одного или двух свойств и/или вызвать более одного или двух методов для объекта в операторе With.

Когда их много, и вы не чередуете .SomeProperty = или .DoSomething с другими вещами, это очень помогает улучшить читаемость.

И наоборот, несколько точек, разбросанных среди множества других вещей, на самом деле намного труднее читать, чем вообще не использовать With.

В этом случае . символы сами по себе могли бы легко потеряться визуально, хотя, конечно, это было бы синтаксически согласовано.

Я думаю, они просто решили не реализовывать это. VB на самом деле не тот язык, где они хотят поощрять односимвольные языковые элементы, и, как активный пользователь VB.Net, я в целом согласен с этим.

Итог: если вы используете предложение With со многими содержащимися элементами, необходимость ссылаться на сам объект не такая уж большая проблема. Если вы используете его только с одним или двумя, возможно, лучше вообще не использовать предложение With.

person ChrisA    schedule 04.03.2010

Я не уверен, что это «ответ» как таковой, но он иллюстрирует еще одну причину, по которой нужна сокращенная ссылка на родителя в With.

Вот пример кода с использованием «голого With» (во всяком случае, так я его называю):

With New frmMySubForm
    .lblLinkLabel.Links.Add(New LinkLabel.Link With {.Name = "link", .LinkData = "someUrl", .Start = .lblLinkLabel.Text.IndexOf("link"), .Length = "link".Length})
    ...
End With

Но на самом деле вы не можете закодировать это, потому что в термине .Start = .lblLinkLabel.Text.IndexOf("link") компилятор ожидает, что все, начинающееся с ., будет членом LinkLabel.Link, а .lblLinkLabel не является.

Я думаю, что было бы хорошо иметь возможность написать что-то вроде:

With New frmMySubForm
    .lblLinkLabel.Links.Add(New LinkLabel.Link With {.Name = "link", .LinkData = "someUrl", .Start = Me.lblLinkLabel.Text.IndexOf("link"), .Length = "link".Length})
    ...
End With

где Me в этой области считается New frmMySubForm.

Да, я понимаю, что я придирчив, и я мог бы легко назначить переменную и т. Д. Но форма-пример - это то, что я часто использую просто из-за предпочтения.

person SteveCinq    schedule 25.05.2017