Option Strict и распаковка объекта в строку

У меня есть древовидное представление, в котором некоторые из трех узлов имеют строку, сохраненную в их объекте тега, а некоторые теги остаются пустыми. Позже я хочу использовать строки для чего-то в узлах, где они существуют.

For Each tn As TreeNode In TreeView1.Nodes
    If Not String.IsNullOrWhiteSpace(tn.Tag) Then
        Call DoTagStringStuff(tn.Tag)
    End If
Next tn

Это работало нормально, пока мне не потребовалось включить option strict, чтобы мой код был совместим с проектом коллег. Я немного не понимаю, как лучше всего распаковать строку из объекта treenode.tag.

Во всплывающем окне с ошибкой предлагается использовать CStr, но у меня создалось впечатление, что функция CStr была только в VB.net как возврат к VB6 и действительно не должна использоваться для нового кода. Если я попробую tn.Tag.toString в приведенном выше коде, я получаю сообщение об ошибке во время выполнения, когда не удается вычислить Nothing.toString.

Как правильно это исправить? Должен ли я вообще использовать объект тега для хранения строковых значений в первую очередь, или есть лучшее свойство treenode, которое не требует распаковки, которое я могу использовать для этого?

Изменить: я думаю, возможно, это было бы правильно?

For Each tn As TreeNode In theNode.Nodes
    If tn.Tag IsNot Nothing Then
        Call DoTagStringStuff(DirectCast(tn.Tag, String))
    End If
Next tn

За исключением того, что я больше не проверяю пустую или только пустую строку.


person Odinsonnah    schedule 24.06.2013    source источник
comment
Нет, CStr () не является возвратом. Вместо этого вы можете использовать метод ToString () объекта, если хотите. На самом деле это свойство Tag, которое является возвратом VB6. Обычно вы избегаете его использования, отделяя модель от вида.   -  person Hans Passant    schedule 24.06.2013
comment
Tag присутствует на большинстве (если не на всех) элементах управления. Я не вижу проблемы в использовании этого в некоторых случаях. Я не знаю случая TS, но это не возврат как таковой;).   -  person Styxxy    schedule 25.06.2013


Ответы (2)


Я немного не понимаю, как лучше всего распаковать строку из объекта treenode.tag.

Во-первых, здесь нет бокса или распаковки. Поскольку String - это класс, переменная Object может напрямую содержать ссылку на String без упаковки. Упаковка происходит, когда вы сохраняете тип значения (Structure) в переменной Object.

При этом, чтобы извлечь значение, поскольку вы знаете, что всегда храните String, вы можете использовать DirectCast для извлечения значения:

For Each tn As TreeNode In TreeView1.Nodes
    Dim tag = DirectCast(tn.Tag, String)
    If Not String.IsNullOrWhiteSpace(tag) Then
        Call DoTagStringStuff(tag)
    End If
Next tn

Если другие типы потенциально могут быть сохранены в Tag или если Tag можно оставить пустым, тогда могут быть уместны другие преобразования.

person Reed Copsey    schedule 24.06.2013
comment
В том-то и проблема, иногда тег оставляют как Nothing, но это единственное исключение. Если что-то и есть в теге, я знаю, что это String. Я думаю, что мне может понадобиться такой метод, как DirectCast( tn.Tag, String), который достаточно умен, чтобы превратить tn.Tag значение Nothing в String значение Nothing. - person Odinsonnah; 24.06.2013
comment
@Odinsonnah В этом случае вы можете просто поставить нулевую проверку перед DirectCast или использовать CType или CStr вместо DirectCast. - person Reed Copsey; 24.06.2013
comment
Я протестировал код, и оказалось, что DirectCast действительно работает здесь корректно, даже когда тег - ничего, так что это полное решение для меня. - person Odinsonnah; 25.06.2013

Использование CStr для приведения / преобразования тега в строку совершенно законно:

DoTagStringStuff(CStr(tn.Tag))

Если вас не интересует синтаксис CStr, вы можете использовать вместо него DirectCast или CType. CStr - это, по сути, просто сокращение от CType(x, String). Хотя CStr действительно существовал в VB6, его использование не считается устаревшим. Он по-прежнему считается функцией основного языка VB.NET.

Технически, поскольку вы знаете, что свойство ссылается на объект String, лучшим выбором будет DirectCast:

DoTagStringStuff(DirectCast(tn.Tag, String))

DirectCast немного более эффективен, когда вы не планируете выполнять какое-либо преобразование значения. В качестве дополнительного преимущества он более самодокументируется. Любой, кто прочитает эту строку, будет знать, что Tag - это ссылка на объект String, тогда как если бы вы использовали CStr или ToString, это было бы неочевидно.

person Steven Doggart    schedule 24.06.2013