Category Archives: .NET

DIM x AS NEW SpeechSynthesizer

0
Filed under .NET, VB Feng Shui

Here’s an interesting one for you.

I was playing with the SpeechSynthesis namespace recently when I ran off into a coding ditch. You know, one of those times when things are moving along nicely, and you swerve to avoid some minor nit, only to find yourself stuck upside down with the wheels half sunk in muck, trying to claw yourself out with an ICE and log files…

Anyway, I had this:

Public Class Connect
   Private WithEvents rSynth As New SpeechSynthesizer
   ...

And a little later in the class, I was using it like so…

      If rSynth.State <> SynthesizerState.Speaking Then
         rSynth.SpeakAsync(Speak)
      End If

Simple enough.

But it didn’t work. State was always coming back Ready, not Speaking, so I was getting a rather laughable stuttering intro to tracks as they were playing… “Now…Now…Now…Playing….Playing….Swerve…Playing….Swerve…”

(Sorry, the app in question is a little MP3 player plug in to announce tracks and allow you to navigate through the player using only a remote and no screen.)

I tried several different approaches but none worked. I could never get the proper state of the synthesizer to be reflected.

Then, on a lark, I remove the New from the SpeechSynthesizer declaration line:

Public Class Connect
   Private WithEvents rSynth As SpeechSynthesizer
   ...

And just assigned a new instance to the rSynth var from Sub New.

It worked!? Huh?

What was going on here?

I’m still not 100% sure, and the documentation on the NEW modifier for a DIM statement certainly doesn’t help to clarify things. From what I can tell, it looks like each reference to the regional var rSynth ends up retrieving a new SpeechSynthesizer object. Definitely not the behavior I was expecting. And not behavior I’ve seen before given this use of the New clause.

In reality, I’ve had far too many lessons about Dim x as New from VB6 to normally use it like this anyway. I guess I thought VB was past all that now in .NET, but I’m slowing learning that VB.NET is every bit as quirky as VB6, just differently so.

Ah, progress.

Very Cool VS2008 Add In

0
Filed under .NET, Utilities, VB Feng Shui

I’ve always been a big fan of the MZTools addin for VB6, so it was a little disappointing, if not understandable, that for his .NET foray, he’s wanting to get paid a little something for it.

Not that that’s bad, I just haven’t been able to commit to MZTools for .NET just yet.

In the meantime, I stumbled across a very slick little VS addin called DPack.

It’s actually a small set of different addins. Doesn’t look like you get the source, which is unfortunate, but the features are pretty slick, plus they work in VB, C++ and even C# and Ruby.

The Code Browser alone is worth the download. With one keystroke, you get a window like this:

image

It’s nicely sorted, browsable, and with one other click, takes you directly to the given code element. Even better, you can assign direct keystrokes to filter only methods, classes, properties, etc. By default, ALT-M shows just the methods in the current file, for instance. Reminds me of the old F2 (Function list) key that used to be in older VB’s. I missed that key<sob>.

Also particularly nice is the “Surround Selection With…” feature. You can’t customize the surrounding text but they give you the most common items (surround with TRY CATCH, FOR NEXT, DO WHILE, REGION, etc, etc.), so that’s not too bad.

It seems very quick and stable. And the best part is, it’s completely free!

Line Numbers and VB.NET

3
Filed under .NET, Troubleshooting, VB Feng Shui

Line numbers have been around ever since the dawn of time in BASIC.

Remember this classic:

10 Print “Hello”

20 Goto 10

But what many people may not know is that line numbers still exist in VB.Net!

Yep, that’s right, you can write the above routine, as I show it, in VB.NET.

Well, with one exception. Line numbers in .NET are treated as full on labels, and labels must be followed by a colon. So you’d have this in .NET:

10: Print “Hello”

20: Goto 10

Now, before I start getting hate mail about GOTO’s and such, let me say that I’m only a fan of a GOTO in a few very controlled circumstances.

But GOTO’s are the point here. Way back in the Visual Basic (Pre .NET days), line numbers combined with the ERL function made for a surprisingly effective field debugging tool. If you line numbered your code before compiling, and used ERL appropriately during your error handling, you’d be able to precisely pinpoint the offending line of code very quickly and painlessly.

I’ve used that approach for years, and even wrote an article in VB Programmers journal at one point about a very extensive generic error handling facility.

Recently, I decided to look into updating that facility for VB.NET, and unfortunately have good and bad things to report.

First the good.

  • As I said before, VB.NET still supports line numbers and the ERL statement, as well as all the old favorites ON ERROR RESUME NEXT, ON ERROR GOTO, RESUME, and RESUME NEXT.
  • You can easily compile VB.NET projects from the command line, making it relatively trivial to create a simple batch file to line number your code, compile it, then clean up the line numbered version.
  • VB.NET supports a much more sophisticated StackTrace/StackFrame functionallity that would seem, at first glance to obviate the need for ERL entirely.

but now the bad…

  • The StackTrace/StackFrame functionality works fantastically, as long as you’re willing to ship the program debugging database (PDB files) that are generated when you compile your project.
  • Worse still, you can’t use the old style ON ERROR GOTO, in the same method as the new style TRY CATCH FINALLY exception handling.

image

  • And finally, the ultimate bit of nastiness. While trapping an error with the old style ON ERROR GOTO will generate a standard exception (See the Err.GetException method), trapping an exception with structured exception handling (also known as SEH, or TRY CATCH), does not affect the ERR object at all, specifically, throwing an error in a TRY block will not set the ERL value, even if the code is line numbered.

image

So what’s the end result of all this?

Basically, do not even bother with ON ERROR GOTO style error handling in VB.Net. Even though it would appear to be supported, and even though retrieving the line number of the failing code isn’t possible without shipping your PDB, the fact that line numbers aren’t reported in code using SEH makes them pretty much useless. SEH is quite useful in many situations, so you wouldn’t want to not use it solely because of this.

But that doesn’t address two very real issues.

  1. Line numbers in stack traces are an incredibly useful debugging tool
  2. You don’t want to distribute your PDBs just to get line numbered stack traces if at all possible.

More to ponder…

Choices in Utility Function Implementation

0
Filed under .NET, VB Feng Shui

One thing I’ve begun to notice about VB.NET is that there are a pile of options as to how you might implement a particular piece of functionality. I’m still not convinced that this is necessarily a good thing, but it is hard to argue with having options.

For instance, I recently needed a function to retrieve the number of elements defined in an enumeration. Now, I realize that enumerations can be sparse, and that creating an array to be indexed by the enumeration values will not work with all enumerations, but that’s a topic for another post.

The first option I thought of was to implement it as a plain ol’ function in a module:

Debug.print GetEnumItemCount(GetType(MyEnum))

    Public Function GetEnumItemCount(ByVal typ As Type) As Integer
        If typ.IsEnum Then
            Return System.Enum.GetNames(typ).Length
        Else
            Return 0
        End If
    End Function

Not terribly interesting and it’s perfectly functional, but it just doesn’t seem particularly .NET-ish. Also, I don’t really care for the “double function” approach (ie calling GetType() to retrieve the enum type descriptor object to pass into the function).

So, any way to improve this?

One way is to get rid of the extra GetType function call. Unfortunately, the only way I’ve seen to do this so far is to pass in one of the enumeration values instead of the enumeration itself (or its type).

Debug.print GetEnumSiblingCount(MyEnum.Value1)

    Public Function GetEnumSiblingCount(ByVal e As [Enum]) As Integer
        Return System.Enum.GetNames(e.GetType).Length
    End Function

I’ve renamed the function GetEnumSiblingCount because that’s exactly what this new function does, return the total number of siblings to the passed in enumeration element.

Unfortunately, this approach still seems a little a lot odd.

My next thought was, why not add an extension method to the enumeration itself, so you could do something like:

Debug.print MyEnum.Count

Unfortunately, since MyEnum is a type and not considered an actual object in any sense, you can’t invoke a method on it, or even define one on it for that matter.

You can, however, get close, by defining an extension method on the Type object itself:

Debug.Print GetType(MyEnum).Count

Module EnumExtender
    <extension ()> _
    Public Function Count(ByVal typ As Type) As Integer
        If typ.IsEnum Then
            Return System.Enum.GetNames(typ).Length
        Else
            Return 0
        End If
    End Function
End Module

The downside here is that we’re extending not just enum types but all types, and extending anything other than enums with this function doesn’t make much sense.

Interestingly, there’s yet another option; extend the enum elements themselves.

Debug.print MyEnum.Value1.SiblingCount

Module EnumExtender
    <extension ()> _
    Public Function SiblingCount(ByVal anEnum As [Enum]) As Integer
        Return System.Enum.GetNames(anEnum.GetType).Count
    End Function
End Module

However, this also has the same problem as a previous try in that it just doesn’t feel right to ask an enumeration element for some property of it’s containing type.

Ok, how about just changing up the definition of the enumeration itself:

    Public Enum MyEnum
        Value1 = 0
        Value2 = 1
        Value3 = 2
        Count = 3
    End enum

Short, sweet, no compiler tricks or reflection.

But. It doesn’t work with existing, already defined Enumerations, and since the Count is part of the enumeration, the actual count of the enum is 4, not 3, which would seem to be confusing in the long run.

I’m sure there’s many more possibilities as well, and, hopefully, I’ve missed a better one and someone out there will let me know it!

Long story short, my first inclination, the plain ol’ function-in-a-module GetEnumItemCount(), seems the best solution for this particular piece of functionality.

In reality, the best solution for most of these sorts of generic, application-wide, stateless utility functions seems to be the plain ol’ function-in-a-module.

Fixing System.String

0
Filed under .NET, Languages, Rants, VB Feng Shui

String manipulation is a very different beast in VB.NET than in VB6. In fact, I’d wager that it’s the one area that trips up programmers new to VB.NET more than any other aspect of the language.

I’ve talked about some annoying aspects of System.String before, but this go round, I’m going to concentrate on shared methods.

Shared Methods are methods that are invoked via the class type itself, and not via an instance of the class.

For instance, with strings, you have a nicely named IsNullOrEmpty  function that you’d expect would return a true/false indicating whether the string in question is null or empty. Unfortunately, you’d be only half right.

Bring up the Object browser and find the String class, then highlight the IsNullOrEmpty method and you’ll see this:

image

Notice the Shared keyword. That indicates that this method IS NOT an instance method, thus you can’t invoke it via a specific instance of a string; rather, you must invoke it via the String class directly.

So, you can’t do this:

Dim s as string
If s.IsNullOrEmpty Then

But you can do this:

Dim s as string
If String.IsNullOrEmpty(s) Then

Now, it makes perfect sense, from a purely technical perspective, that invoking an instance method on an uninitialized object wouldn’t work anyway, so a method like IsNullOrEmpty wouldn’t make sense to be an instance method, since attempting to invoke it via a variable that hadn’t actually already been initialized would result in an “Object not Set” error.

However, this is VB, not some ivory tower exercise in theoretical language design. If I’m going to invoke a method like IsNullOrEmpty, I’m expect to be able to do so against an instance. Having to invoke it via the String class is just so utterly unintuitive, it defies all reason.

Oddly, the very argument that I note above in favor of using a shared method for IsNullOrEmpty is violated by another string property, Length. Here’s a property that is definitely an instance property, but causes VB code to fail (with the Object Not Set error) when invoked on a variable that hasn’t actually been set to value yet.

Is this just an arbitrary oversight, a design flaw, or an intentional “feature” of the language? I can’t answer that.

But, realistically speaking, I can say that it’s utterly frustrating to have elements of a language, such as these, behave so drastically different from one version to another. It doesn’t matter that the syntax is different (x.Length vs Len(x), for instance), there is an expectation there that simply is no longer met and does nothing but confuse.

Fortunately, with VB 2008, there is a relatively trivial way to correct these problems, and likely a host of other similar issues.

It’s called “extension methods”.

To create an IsNullOrEmpty that works like any reasonable person would expect it too, just put this in a Utility module somewhere in your project:

Imports System.Runtime.CompilerServices

Module StringExtensions

    ''' <summary>
    ''' Returns True if the current string instance is nothing or a null string
    ''' </summary>
    ''' <param name="aString"></param>
    ''' <returns></returns>
    <extension ()> _
    Public Function IsNullOrEmpty(ByVal aString As String) As Boolean
        Return String.IsNullOrEmpty(aString)
    End Function
End Module

The Imports System.Runtime.CompilerServices is only used during compilation. You can actually continue to target the .NET runtime v2.0, even if you use this code (however, you still have to compile the code from VS2008, it won’t work in VS2005).

You tag the new version of IsNullOrEmpty with the <extension()> attribute to  mark it as an extension method.

The first parameter of an extension method is required and is an argument of the type of class that you’re extending, in this case the String class.

You can have additional arguments if necessary, but you don’t need any for this method.

This trick takes advantage of the fact that even though the String class already has a method named IsNullOrEmpty, the function signature is not the same as this one (since ours has the implicit first argument). This is effectively an overload and it allows VB to know to call the new method if invoked against an instance, and the old one if invoked against the String class directly (which is exactly what’s being done within the method itself!).

There are several other “shared” methods on the string class that can similarly be extended to more intuitive instance methods in this way, for instance:

  • Compare
  • Concat
  • Format
  • Join

Length could also be added to this list but you can’t quite treat it the same, since it’s a property, and the Extension attribute can’t be applied to properties.

Finally, extension methods can be unbelievably useful for associating functionality with specific classes that you can’t extend in any other way, but, as always, you need to be careful with how much you extend a  class.

For example, it might be tempting to extend the String class with all sorts of path/file/folder manipulation and parsing logic, so that you could do something like this:

dim s as string = "c:\myFolder"
debug.print s.DriveLetter

but doing so could quickly clutter the String object and Intellisense.

As usual with these sorts of techniques, use judiciously.

One Big Control or Lots of Little Ones (redux)

0
Filed under .NET, ASP, Rants, VB Feng Shui

Some time ago, (or here in the wonderfully virtual web world), I questioned the whole aspect of all this pile of controls in ASP.NET. Of course, you’ve got the grids and listviews, and you also have all the radio buttons, checkboxes. But then you’ve got a separate validator for each kind of validation you want to use, and even validators to let you combine other validators in “AND” and “OR” logical relations.

My thoughts were “Jeez. this is madness.”

Wouldn’t a single control that you could adapt to different display behaviors, validation rules etc be much easier to work with and create a more maintainable solution?

Well, apparently someone at Microsoft had the same bright idea, at least with the new ListView control in ASP.NET 3.5.

Take a read of Fritz Onion’s article in the latest MSDN magazine.

He describes the new ListView as a control that can “literally replace all other databinding controls in ASP.NET. That’s right. Every last one.”

Now, if they’d do the same for that validation nonsense, we might be getting somewhere!

A Grousing About Properties in .NET

0
Filed under .NET, Rants, VB Feng Shui

I’ve started playing more and more with .NET lately. There’s a lot to like, a lot to dislike, and a few things that left me scratching my head.

One is this new fascination with moving regional (or class scoped variables) up to right on top of the properties that are wrapping them.

You’ve no doubt seen the pattern.

In old school VB6, you’d have something like this:

    {top of class}
    Private _MyPropVar As Boolean

    {lots of code here}

    Public Property Get MyProp() As Boolean
        Return _MyPropVar
    End Get

    Public Property Let MyProp(Byval NewValue as Boolean)
       _MyPropVar = value
    End Set
    {code continues}

And in the New Order, you have this:

    {other code}

    Private Shared _MyPropVar As Boolean = True
    Public Shared Property MyProp() As Boolean
        Get
            Return _MyPropVar
        End Get
        Set(ByVal value As Boolean)
            _MyPropVar = value
        End Set
    End Property

    {code continues}

Now, the pundits out there claim that the ability to move the definition of the variable that stores the property value down in the code to where the property is actually defined is a good thing.

And it very well might be.

But if that variable is used elsewhere in the class (it is, after all, visible to the entire class), then it makes more sense to me for it to be grouped with other such class scoped variables at the top of the class, and not buried within the class.

What’s most frustrating about this, though, is that the language designers had the perfect opportunity to solve this problem elegantly, and didn’t.

The simple introduction of a property scope would have done the trick. Then for those variables that are ONLY used to track the contents of a property, you’d have this (note the _MyPropVar definition has moved to INSIDE the property declaration):

    {other code}

    Public Shared Property MyProp() As Boolean
        Private _MyPropVar As Boolean = True
        Get
            Return _MyPropVar
        End Get
        Set(ByVal value As Boolean)
            _MyPropVar = value
        End Set
    End Property

    {code continues}

Now there may be significant ramifications involved that prevented this change, and I’m certainly no expert at compiler design or implementation (though I have implemented a pseudo-code compiler scripting language used in a commercial product).

But this just doesn’t seem like all that big a deal to have implemented and would have cleanly resolved where to put variables of both persuasions (ie those that are used by ONLY a single property, and those that are truly class scoped and used my multiple properties/methods).

Personally, I think this was a bit of a “good enough” decision.

Practically, I think I’ll stick with locating truly class-scoped variables at the top of the class, and ONLY bury variables that really are only accessed by a single method/property.

Damn, I Gotta Get Into .NET

0
Filed under .NET, VB Feng Shui

I’ve been trying to make a point of reading more .NET code lately.

Maybe it’s Scott Hanselman’s Weekly Source Code.

Or maybe it’s that Code Project gadget on my Google home page.

At any rate, I just ran across a project there call LinFU (don’t ask what it stands for), but…wow.

It reminds me of the Black Belt columns by Matt Curland ages ago in Visual Basic Pro (or whatever it was called then, now Visual Studio Magazine). There hasn’t been articles like his in that rag for years. (and btw, if you still do VB6 and don’t have his Advanced Visual Basic 6, I’d highly recommend getting a copy).

Anyway, it’s stuff like Philip Laureano’s LinFU that really is making .NET seem more and more attractive.

Syntactic Sugar

5
Filed under .NET, Rants, VB Feng Shui

What’s with this?

I’ve seen this term bandied about, usually referring to some new feature in VB, and usually in a disparaging way.

Why?

I thought pretty much everything about a 3 or 4GL was syntactic sugar. Without that sugar, we’d be coding in assembler or hex opcodes. I mean, an IF THEN ELSE construct is just syntactic sugar for a bunch of JNEs or JEQs, right? Hell, object oriented code is nothing but syntactic sugar for an array of type structures and function calls with an index as their first argument (the hidden ME pointer in all OO compiler code).

Sounds more like just so much L337ism to me.

I say bring it on. As long as it makes sense, expands the language in useful ways, and isn’t required to make use of the language, the more the merrier. My only concerns would be:

  • Any additional syntax that’s required in order to successfully use the language. That’s VB.NET’s biggest problem now, with respect to adoption by users of VB.
  • Compatibility breaking changes

Still, I think ANDALSO is a tad corny, nice, but corny. So shoot me.

Snippets

2
Filed under .NET, Rants

So, how useful do you find code snippets to be in VS2005? I mean, beyond the “I don’t know how to do something, aha! here’s an example!” use that would be better served up in expanded help file examples.

On the surface, I suppose they could be handy in some circumstances. For instance, setting up TRY CATCH blocks maybe, or….um… ok, having a hard time coming up with other examples. I suspect snippets are one of those gizmos that make you “feel” more productive without actually making anyone truly more productive. They seem like Stephen Colbert‘s answer to developer performance.

My problem with these kinds of macro code “generators” is that they just seem like so much “cut and paste” programming. If you’ve every had to work on code that was built by cut and paste, you know it’s more fun to steam your eyeballs out of their sockets.

If a piece of code warrants being “set up” as a snippet, it probably ought to be encapsulated into its own function/sub/method/whatever, where it can be reused properly.

Here’s a sample snippet for “iterating through a collection”:

      ' Iterate through a collection
        For Each name As String In names

        Next

Now maybe I’m just being a curmudgeon here, but that comment, I’d have to redo, and the rest of it, I can type in less time than it’d take to find the snippet, esp with intellisense. Sure, I could also set up a shortcut for it, but even then, does this sort of thing really save time? Or rather, does it save real time?

You might make the argument that the snippets for creating properties can save time, but if I’m creating that many properties, that consistently, I’m guessing I’m going to use something like MyGeneration instead.

And in the end, a snippet might save a few keystrokes here and there, but, when you look at the entire life span of a project, I’d wager that even if you snorted snippets and peed the Quake physics engine, you’d be lucky to save yourself a few thousandths of a percentage point of the total time you spent coding.

Makes me wonder what the Freakonomics guys would say about them.