Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

The previous post I made got me thinking about the Legacy code I use, so I'll post what I've been doing with the hopes of finding an easy workaround so I can avoid using the Legacy code as a crutch.

 

I've continued to use Legacy code for string functions (Len, Mid, Left, Instr, etc.) simply because they work much better / easier than the .NET equivalents. Otherwise, you I keep getting errors, which are a pain to workaround.

 

Example 1...

 

Dim str as String

Dim i as integer

i = Len(str)

i = str.Length

 

In this example, the Legacy line works, but the last line bombs because no value as been assigned to "str" yet. Very annoying since I do not want to check a string everytime I want it's length to see if has a value.

 

Example 2...

 

Dim str as String

Dim st2 as String

str = "ABC"

str2 = Microsoft.VisualBasic.Left(str, 5)

str2 = str.Substring(0, 5)

 

Again, in this example, the last line crashes. Very annoying. Why can't it just bring back the three character like the previous Legacy line does? (I know the answer is because the string is an array, and there's not 5 elements in the array. But still... very annoying.)

 

I've only considered one practical solution to these issues, and that is to create my own equivalent string functions, where I would pass the string, and then using only .NET code, I check for length and whatever other conditions I'd have to in order to get them to work. But if I'm going to do that, I might as well use the Legacy code since that's what it's already doing.

 

So am I missing something? Or do all the diehard "anti-Legacy" people make your own cumbersome string functions that you have to include in every project? Or is there some setting I can flip to make all the above work without bombing out on all the .NET string functions?

 

Thanks for your input.

Posted

Here's my take:

 

Example 1:

 

Dim str as String = ""

Dim i as integer

i = Len(str)

i = str.Length

 

Example 2:

 

Dim str as String

Dim st2 as String

Dim len As Integer

str = "ABC"

str2 = Microsoft.VisualBasic.Left(str, 5)

 

len = str.Length()

If len > 5 Then len = 5

str2 = str.Substring(0, len)

 

Your examples are very bad examples. In real applications you cannot make assumptions like you have here. If you're doing that you should change your practices. Just because VB 6 let you get away with things like this doesn't mean you should do them.

Here's what I'm up to.
Posted
Which is the main reason to remove the VB6 reference. You should also turn Option Strict on. These two things will increase the quality of code you write. It may take experaince to increase it in other ways, but this is a deffinite first step. Keep in mind to the performance implications of calling VB6 code and the lack of portability to C# or even to newer version of VB.NET as they phase out legacy support.
Posted

I do have Option Strict On -- an invaluable line that everyone should use. However, I disagree about the string stuff.

 

>> Your examples are very bad examples.

 

I don't really care if my examples are bad. It's the principal I'm talking about. Subroutines are meant to make coding easier, and if it turns out that the legacy string functions become obselete, then I (and most everyone else that doesn't want to type up a storm) will create their own string functions utilizing the .NET functions.

 

For although [Dim str as String = ""] would obviously be better in this example, not all objects with string properties are going to be initialized that way, and that's where the sudden errors come into play that I shouldn't have to suddenly worry about. Likewise, I think this is just ridiculous...

 

len = str.Length()

If len > 5 Then len = 5

str2 = str.Substring(0, len)

 

Who's going to code that way every time you need to do a substring? No one. Instead, you'd make your own string library with its own length function to do this for you. That way you trim down three lines into one everywhere in your code, while making it flexible to accept any length to avoid mistypes.

 

So yes, while I agree legacy code should be avoided for the most part, it's still downright goofy to have to re-create functions that already existed. Don't get me wrong -- the properties included with types (such as strings) are great for OOP, but in order to not have to babysit every line of code, it only makes sense to re-create certain functions in a library, which is something MS could have created themselves that would use .NET functionality so we could all be on the same page, rather than everyone writing their own.

  • Moderators
Posted

JD, I really need to disagree with this statement...

"Who's going to code that way every time you need to do a substring? No one."

 

In the real world you would never get the Length of a string (or any property) unless it has already been asigned a value. Regardless of the property I need from str I will always check its' length first...

 

If str.Length > 0 then

Visit...Bassic Software
Posted
JD, I have to say that the reason you think that it is correct to be able to get away with these bad practices is because VB6 has allowed you to and taught you that it is OK. As an example:
Dim str1 As String = "ABC"
Dim str2 As String = str1.Substring(0, 5)

This is ambiguous. If it just returns the three-character substring, then what happens to the program that demands a five-character string? It should throw an exception in that case. Also, you should be initialising all your variables, be they String, Integer or otherwise. You should not just use an uninitialised Integer as zero (even though you can as it's a value type) because someone looking at your code is not to know whether you intended it to be zero or it was a mistake. That someone might be you coming back to old code years later. VB.NET attempts to force you to take into account all the possible results and make sure you have coded correctly for each one. The fact that VB6 allowed you to make lazy assumptions is one of the main reasons VB has been regarded as a "toy" language for so long. I think that VB.NET is a really good language that retains the good features of previous VB versions while replacing the features that, while being convenient, are considered to encourage "bad" practice by the rest of the development community.

Posted
The lateral thinker can also do things like this:
str2 = str1.Substring(0, Math.Min(str1.Length, 5))

Don't assume that everyone wants things to work the way you do. If you want those functions then create them but many people want to write code that deals with possible errors rather than ignoring them and making assumptions.

Posted

>> In the real world you would never get the Length of a string (or any property) unless it has already been asigned a value.

 

I disagree, because you can't always know what has been assigned a value unless you check it every time. As I said earlier, if I'm using a new, unknown object with hidden string properties and functions, I can't assume every string it returns has a value, which means [if str.Length > 0 then] might crash if the object returns Nothing rather than "". Just like in Machaira's example, the line [len = str.Length()] could crash if he hadn't plainly seen in a previous line that str had been given a value. But what happens if someone later on adds a subroutine that assigned Nothing to str? That line will blow up.

 

>> I think that VB.NET is a really good language that retains the good features of previous VB versions while replacing the features that, while being convenient, are considered to encourage "bad" practice by the rest of the development community.

 

I truly can see some of everyone's points, but I still don't understand why it would be considered "bad" practice to create a string library (that only uses .NET code) to simplify these tasks, rather than write extraneous code every time. I acknowledge that VB6 oversimplified some things. However, if a subroutine does what you need it to do, then it's doing it's job, and I don't see the "crime" in creating a robust substring function what returns what I expect it to, regardless of any value it could have.

 

Because while this line almost works [str2 = str1.Substring(0, Math.Min(str1.Length, 5))] I don't want to write it every time, which is where a library would be great to include it instead. And then within it, I can first verify that str1 does not have a value of Nothing. Because if you don't, then that line will crash as it stands.

Posted

JDYoder, you are forgetting that a String is a reference type. It is endowed with some behaviour that resembles a value type but it IS a reference type. Personally, I wouldn't use any reference type object that I hadn't created myself without first checking whether it "Is Nothing", and you should do this with strings as well. Try this code and see if it does what you think it should:

        Dim str As String

       MessageBox.Show((str Is Nothing).ToString())
       MessageBox.Show((str = Nothing).ToString())

       str = ""

       MessageBox.Show((str Is Nothing).ToString())
       MessageBox.Show((str = Nothing).ToString())

 

You hit the nail on the head when you said "function what returns what I expect it to". Just because you expect something doesn't mean it is right or what the rest of us expect. Read the help description of the Substring function you mention and you'll see that the second argument is "The number of characters in the substring". So that function does exactly what you would expect from that description. If it behaved the way you want it to then anyone who wanted the current behaviour would then have to go and write their own function. MS have decided that they like the current implementation so live with it. They could have done a million other things, and may well in time, but what we have now is what we have so if you want more then go ahead and write what you need.

 

The most important thing I think is this: Strings are reference type objects so treat them as such. They behave like value type objects in some ways, which is a convenient bonus, but they are objects on the heap, not the stack.

Posted

To be honest, identification of your data types and entry methods should have been assessed in your analysis and design stage, before you even reach the code stage. In itself, these stages dictate that you should be checking the data that's entered as soon as it is entered. It's a simple practice to adopt that will save you hours of debugging later...

 

 

Paul

  • Leaders
Posted

The issue here merely seems to be the internal checks that each function does.

 

Sure the Len(s) function checks if s is Nothing before returning a value, but you know the old saying: "it is better to be safe than be sorry"

You should also do your own check when trying to get the length.

The .Length property is assuming that you know this already so that it can return quicker (at least I hope it does).

 

Although, if you are disappointed in any function because it doesn't do enough checks for you, you can always make your own that does those checks.

:)

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted
One more thing with regards to the Len function. It was never intended to return the length of a String. This is a welcome side-effect, and its primary use in the real world, but Len actually returns the amount of storage space a variable would occupy in a file. You can use Len on non-String variables and get the number of bytes they would occupy. Len returned the number of characters in a String because that was how many bytes it would occupy. A String that is a null reference would occupy zero bytes, so Len returns zero for a null reference String. Len is not accurate in VB.NET, however, because characters are Unicode and take two bytes each, I believe, so Len no longer does what it was intended to do and return the amount of space it would take to store a String object in a file.
Posted

Interesting. However, it does appear to work since the following line returns 11...

 

MessageBox.Show(Microsoft.VisualBasic.Len("Hello World"))

Posted

Like I said, the purpose of Len was to return the number of bytes an object would occupy when saved to a file. The happy coincidence was that this was also the length of a string object in the old days. Now that strings are Unicode instead of ASCII, Len no longer functions as it was originally intended.

 

I'm not saying that Len does not return the length of a string or that you cannot use it in that capacity. I was merely pointing out that that is not its originally intended purpose and that is why it returns zero when passed a null reference.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...