2

I have a treeview where some of the treenodes have a string saved into their tag object and some of the tags are left as nothing. Later on I want to use the strings for something, in the nodes where they exist.

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

This worked fine until I needed to turn on option strict to make my code compatible with a co-workers project. I'm a bit confused about how to best unbox the string from the treenode.tag object.

The error popup suggest using CStr, but I was under the impression that the CStr function was only in VB.net as a throwback to VB6, and really shouldn't be used for new code. If I try tn.Tag.toString in the above code, I get an error at runtime when it fails to compute Nothing.toString.

What is the right way to fix this? Should I even be using the tag object to hold string values in the first place, or is there a better treenode property that wouldn't require unboxing I can use for this?

Edit: I think perhaps this would be correct?

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

Except I'm not checking for an empty or only whitespace string anymore.

Odinsonnah
  • 73
  • 1
  • 5
  • No, CStr() is not a throwback. You can use the object's ToString() method instead if you prefer. It is actually the Tag property that's a VB6 throwback. You in general avoid its usage by separating the model from the view. – Hans Passant Jun 24 '13 at 17:23
  • The `Tag` is present on most (if not all) controls. I don't see the problem of using this in certain cases. I don't know the case of the TS, but it isn't a throwback per se ;). – Styxxy Jun 24 '13 at 20:45

2 Answers2

0

I'm a bit confused about how to best unbox the string from the treenode.tag object.

First off, there is no boxing or unboxing involved here. Since String is a class, an Object variable can directly hold a reference to a String without boxing. Boxing occurs when you store a value type (Structure) within an Object variable.

That being said - to extract the value, since you know you're always storing a String, you can use DirectCast to pull out the value:

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

If other types could potentially be stored in the Tag, or if Tag may be left empty, then other conversions may be appropriate.

Community
  • 1
  • 1
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • That's just the problem, sometimes the tag is left as `Nothing`, but that's the only exception. If there's anything in the tag at all, I know it's a `String`. I think what I might need is a method like `DirectCast( tn.Tag, String)` that's smart enough to turn a `tn.Tag` value of `Nothing` into a `String` value of `Nothing`. – Odinsonnah Jun 24 '13 at 17:22
  • @Odinsonnah You could just put the null check before the `DirectCast`, or use `CType` or `CStr` instead of `DirectCast`, in that case. – Reed Copsey Jun 24 '13 at 17:25
  • I tested the code, turns out that DirectCast does in fact work correctly here even when the tag is nothing, so this is a complete solution for me. – Odinsonnah Jun 25 '13 at 13:33
0

Using CStr to cast/convert the tag to a string is totally legitimate:

DoTagStringStuff(CStr(tn.Tag))

If you don't care for the CStr syntax, you can use either DirectCast or CType, instead. CStr is essentially just shorthand for CType(x, String). While CStr did exist in VB6, it is not considered out-dated to use it. It is still considered to be a function of the core VB.NET language.

Technically, since you know that the property references a String object, the best choice would actually be DirectCast:

DoTagStringStuff(DirectCast(tn.Tag, String))

DirectCast is slightly more efficient when you don't intend any conversion of the value to take place. As a side benefit, it's more self-documenting. Anyone who reads that line will know that the Tag is a reference to a String object, whereas if you used CStr or ToString, that wouldn't be obvious.

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105