tfowler Posted October 3, 2005 Posted October 3, 2005 I just wanted to get some opinions about the best practice for placing control characters into strings. I guess I can always still use the old Chr function (or ChrW), but without creating constants or memorizing the ASCII tables, it is not immediately clear which control character I am inserting. My favorite is the new Microsoft.VisualBasic.ControlChars namespace. However, I've read where a lot of people suggest staying away from the Microsoft.VisualBasic namespace, because of compatibility with the other .NET languages and confusion when dealing with non-VB developers. How important is this? What do you think? Todd Quote
Leaders snarfblam Posted October 3, 2005 Leaders Posted October 3, 2005 I think that you are generally right about staying away from Microsoft.VisualBasic for exactly the reasons you mentioned. I personally exclude it from every project I make because the majority of functions and classes in Microsoft.VisualBasic are essentially nothing more than wrappers for the equivalent .Net classes/functions and only exist for the sake of being able to access the features using the old VB6 names. Others would disagree. For instance, some Visual Basic functions perform certain common sense checks (IsArray first checks if the object is Nothing before returning TypeOf(Object) Is System.Array, and the Len() function similarly checks first to see if the string passed is Nothing before returning String.Length()). Microsoft's take is that Microsoft.VisualBasic is part of the VisualBasic language and is okay to use. As far as Microsoft.VisualBasic.ControlChars specifically, I wouldn't worry much. For those who don't program in VB, ControlChars is self-explanatory and easy enough to convert. Quote [sIGPIC]e[/sIGPIC]
Leaders Iceplug Posted October 4, 2005 Leaders Posted October 4, 2005 I've read somewhere that the basic functions of the Microsoft.VisualBasic namespace such as Len() CInt() CStr() and the like are all optimized by the .NET compiler... causing these legacy functions to run faster in many circumstances. For instance: Const dTab As Char = ChrW(9) Const ddTab As Char = Convert.ToChar(9) 'Guess which one doesn't work. ChrW, a legacy function can be used in Const declarations... the *closest equivalent* in .NET, Convert.ToChar, does not work. Oh yeah, you can make a Const Character for tab like above if you wanted. All other control characters I use Environment.Newline :). Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
Leaders snarfblam Posted October 5, 2005 Leaders Posted October 5, 2005 The functions in the Microsoft.VisualBasic namespace were actually written in .Net (probably either C# or managed C++). You are correct about the example you provided being optimized out, but such optimizations only pertain to constants that can be evaluated at compile time. 'VB Const Test As Char = ChrW(&H11) 'IL .field public static literal char Test = char('\x11') As I've said, most VB functions are wrappers for .Net functions. Let's take a look at the decompiled Len() Function [Vb] Public Shared Function Len(ByVal Expression As String) As Integer If (Expression Is Nothing) Then Return 0 End If Return Expression.Length End Function [/code] When you use Len(), Len() does a safety check and then returns String.Length for you. Granted, Microsoft tried to make these functions idiot proof by checking for null references, but otherwise, this function is nothing more than a wrapper. As far as coversion functions like CInt, CDbl, etc. These are a different story. If you are doing a conversion between numeric types then these can be inlined. This isn't necessarily any better than using .Net conversion classes. 'This: Dim X As Intger Dim Y As Double X = Cint(Y) 'Is compiled as this Dim X As Integer Dim Y As Double X = CType(Math.Round(X), Integer) 'It does nothing more for you than save you some typing. And Calling CInt/CDbl/etc. on a string calls a Microsoft.VisualBasic function that in turn calls Integer.Parse/Double.Parse/etc. Microsoft.VisualBasic tends to use very unstraightforward methods and seldom offers any advantage over a non-Visual Basic method. Your best bet is to understand what is going on under the hood with it so that you know when to use Visual Basic function and when not to. I would say that VB functions will generally run slower, but the difference will also generally be negligible, either way. Quote [sIGPIC]e[/sIGPIC]
Leaders Iceplug Posted October 8, 2005 Leaders Posted October 8, 2005 OK, well, I see the Len() function isn't in the list, but I was referring to the MS link within this thread for conversion functions. http://www.xtremedotnettalk.net/showpost.php?p=433830&postcount=3 I agree that it seems nasty having these functions to use and the .NET equivalent should always be known to you... but of course, MS wants us to use these conversion factors... as you can clearly see within VB 2005 :-\ Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
bri189a Posted October 8, 2005 Posted October 8, 2005 On the subject...ever been in a shop that crossed from VB to C#?; let me tell you it isn't pretty going back and changing a bunch of VB6 legacy code to .NET code - you learn real quick why you should use the .NET method regardless of whether it's VB or not. Quote
Leaders snarfblam Posted October 9, 2005 Leaders Posted October 9, 2005 Here it is, everyone! Functions to get characters without using either Microsoft.VisualBasic or System.Convert. As a matter of fact, it depends on no other classes than itself (and two attributes). <System.Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Explicit)> _ Public Structure MyChrW <System.Runtime.InteropServices.FieldOffset(0)> _ Private [Char] As Char <System.Runtime.InteropServices.FieldOffset(0)> _ Private [short] As Short <System.Runtime.InteropServices.FieldOffset(0)> _ Private [uShort] As UInt16 Private Shared Inst As MyChrW Public Shared Function FromShort(ByVal [short] As Short) As Char Inst.Short = [short] Return Inst.Char End Function Public Shared Function FromUShort(ByVal [uShort] As UInt16) As Char Inst.UShort = [uShort] Return Inst.Char End Function Public Shared Function ToShort(ByVal [Char] As Char) As Short Inst.Char = [Char] Return Inst.Short End Function Public Shared Function ToUShort(ByVal [Char] As Char) As UInt16 Inst.Char = [Char] Return Inst.UShort End Function End Structure This nifty structure allows you to convert characters to their Unicode value (signed or unsigned) and vice versa. This is done by storing a Char, a Short, and a UInt16 in the same location in memory. When a conversion is made, the value is stored as the type to be converted from and then retrieved from the same memory as the type to be converted to. It is type safe and fast, and best of all, tfowler, no more need to worry about the Microsoft.VisualBasic namespace. As a matter of fact, using a similar structure, you can access different ranges of bytes as different types. I've done this to convert various types to bytes (such as the System.Drawing.Color structure). As another example, I've also used this with the Windows API when two Int16s were passed as a single Int32. Quote [sIGPIC]e[/sIGPIC]
tfowler Posted October 11, 2005 Author Posted October 11, 2005 Thanks for all of the discussion guys. Very interesting. MarbleEater: Thanks for the code. Todd Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.