Posts Tagged ‘WTF’

Four Irritating Lines of Code

At many places in the framework, you’ll see properties of types named for the enumerations or types they receive. I was indifferent to that until just now.

I just wrote these four lines of code. It took much longer than it needed to.

BinaryFormatter f = new BinaryFormatter();
f.FilterLevel = TypeFilterLevel.Low;
f.TypeFormat = FormatterTypeStyle.TypesWhenNeeded;
f.AssemblyFormat = FormatterAssemblyStyle.Simple;

Consider the last three lines. None of the enumeration names are even close to the corresponding property on the formatter.

For all three of these, I typed out something like this:

f.FilterLevel = FilterLevel.

[No Intellisense, there’s a problem]

[Backspace repeatedly]

f.

[Intellisense shows up; oh, it’s “TypeFilterLevel”]

f.FilterLevel = TypeFilterLevel.Low;

Maybe the usability studies didn’t make it to System.Runtime.

WTF

This Daily WTF reminded me of a guy I used to work with who would use this pattern in every single function he wrote.

Public Const cSTRINGFOO As String = "foo"

Public Function Foo() As Boolean
    Dim ret As Boolean = False
    Try
        Console.WriteLine(cSTRINGFOO)
        ret = True
    Catch ex As Exception
        ret = False
        Throw New Exception("", ex)
    End Try
    Foo = ret
    Exit Function
End Function

I’m not sure what he was expecting to happen here, but there were some clues:

  • Every function he wrote returned true or false to indicate that it had successfully completed without an exception.
  • Every exception was wrapped in another, except where he forgot and swallowed the exceptions.
  • He would always use constants for string literals, even if he only used the literal once (like above), and even if the constant was much longer than the literal.

Mind you, I discovered this self-imposed standard a while after he quit, so I never really got to the bottom of it.

The Danger of The Code Project

I’d say it’s the sheer number of hacks available with minimal discussion or explanation, coupled with the tendency of these kinds of sites to outrank MSDN on google for certain things. This isn’t necessarily a critique of The Code Project site specifically, but rather internet code snippets in general.

I was writing a Windows service today, and I wanted it to have a tray icon to provide access to some options. This isn’t as straightforward as adding a NotifyIcon component, because by default services aren’t allowed to create windows and so forth.

After some googling I came across this.

Now, bitter experience has already taught me never to trust internet code samples. I won’t go into that. But what was interesting was that this article goes so far as to mention:

I am assuming that Microsoft left this out for a reason…

Well, as it turns out, they did. There are at least a few security concerns in this situation, and one should be more educated on the subject than I am to attempt it. At that point I backed up and went with a client/server control model. It was more robust anyway, but it would take longer to write.

I would be interested to know how many authors of production code grabbed and used this code snippet without a second thought. It was the top search result for my terms, so I’m guessing it would be a high number.

The tendency of people to believe everything they read is of course not new.

Release Day 422: A Vignette


McFunley: did you name this page something impossible to remember correctly on purpose?
McFunley: this is a good anti-querystring hacking technique
DarrelHerbst: the twocheckboxcolumn.aspx?
DarrelHerbst: i remember it
DarrelHerbst: your mind is addled with coffee
McFunley: i typed "twocolumncheckbox" and "twocheckcolumnbox" and "boxcolumnchecktwo" before I got it right
DarrelHerbst: addled


Thread Safety in VB-2003 Events

Brad Abrams had a recent post about how the usual way of raising an event in C#:


protected virtual void OnMyEvent(EventArgs e)
{
    if(MyEvent != null)
    {
        MyEvent(this, e);
    }
}

is not threadsafe. Purely out of curiosity, I wondered if VB handles this the correct way:


protected virtual void OnMyEvent(EventArgs e)
{
    EventHandler handler = MyEvent;
    if(handler != null)
    {
        handler(this, e);
    }
}

Since VB abstracts this away with the RaiseEvent keyword. Unfortunately it doesn’t seem to, as this code:


Protected Overridable Sub OnMyEvent(ByVal e As EventArgs)
    RaiseEvent MyEvent(Me, e)
End Sub

Compiles to this:


.method family newslot virtual instance void OnMyEvent([mscorlib]System.EventArgs e) cil managed
{
      // Code Size: 22 byte(s)
      .maxstack 8
      L_0000: ldarg.0
      L_0001: ldfld [mscorlib]System.EventHandler VbConsoleApp.Test::MyEventEvent
      L_0006: brfalse.s L_0015
      L_0008: ldarg.0
      L_0009: ldfld [mscorlib]System.EventHandler VbConsoleApp.Test::MyEventEvent
      L_000e: ldarg.0
      L_000f: ldarg.1
      L_0010: callvirt instance void [mscorlib]System.EventHandler::Invoke(object, [mscorlib]System.EventArgs)
      L_0015: ret
}

Which has a race condition–it should store the delegate in a local. Generally, my answer to all of these questions is “it is fixed in 2005” – so I’m going to just assume that that is the case here.

Significant Digits for the Innumerate

Suppose you ask me, “how wide is that picture frame?” (No, nevermind why you care how wide the picture frame is. This is a little device I call, “using narrative to make a semi-technical thing sound approachable.)

“About nine inches,” I would say.

Now, suppose your friend Friedrich asks you how wide the picture frame is, and I’m not in the room (let’s say I’m asleep—that’s where I’m a pirate!). You happen to know that Friedrich is of the German persuasion, and if you give him a number in English units he’ll scoff at you and possibly destroy your apartment with a Stuka divebomber.

Thinking quickly, you refer to your wristwatch calculator which you have been wearing since 1988 (in this narrative, your sense of style is atrocious). “There are 2.54 centimeters in an inch – I remember that from high school,” you think to yourself. Doing the multiplication, you smugly report to Friedrich that the picture frame is 22.86 centimeters wide.

Everybody’s happy, right? Not so fast, Copernicus.

I only told you the frame was “about nine inches” wide, remember? That could possibly mean 8.556 inches, 9.210 inches—you really can’t be sure. As a measuring device, I am lazy and inept. Do you want to be held responsible for my lax attitude? No, of course you don’t.

You are really only justified in telling Freddy-boy that the frame is about 20 centimeters wide. Giving him the extra digits of that number just give it the illusion of precision where none exists.

Friedrich measures the frame himself and gets less than 22 centimeters. He punches you in the stomach and leaves you wincing in pain on the floor, cursing me for not giving you a better figure in the first place. Sorry, I just couldn’t be bothered. (You made your bed, now lie in it, dammit!!!)

Oh yes, my point. Well, this kind of thing applies to a lot more than the picture on my desk. If I tell you that you can get $1.32 for a Euro, and $1.89 for a British Pound, you might similarly do the math and tell me that therefore, you can get 0.6984126984126984126984126984127 British Pounds per Euro. Well, you’d be nuts.

Downloading a file async

I suppose that’s one way you might do it, but here is another:

private void button1_Click(object sender, System.EventArgs e)
{
    WebRequest request = WebRequest.Create("http://www.mcfunley.com/stuff/hi.txt");
    AsyncCallback callback = new AsyncCallback(this.GotFile);
    IAsyncResult res = request.BeginGetResponse(callback, request);
}

private void GotFile(IAsyncResult r)
{
    if(this.InvokeRequired)
    {
        this.Invoke(new AsyncCallback(this.GotFile), new object[]{r});
        return;
    }
    WebRequest request = (WebRequest)r.AsyncState;
    WebResponse response = request.EndGetResponse(r);
    using(StreamReader reader = new StreamReader(response.GetResponseStream(), true))
    {
        this.richTextBox1.Text = reader.ReadToEnd();
    }
}

Re: “Best Method Names Ever”

From Brad Abrams.

I would have to say the best function name ever is definitely Function Batman.

But if we’re limiting it to Microsoft products, I guess I’d have to say I’m often surprised by the number of internal framework methods that are labeled “hacks.”

.NET Framework hacks

Visual Basic Case Insensitivity

Here’s something that bit us today. Somehow, our big solution has been tricked into thinking that the System.Web.UI.Control.DataBind method is actually Databind (with a small “b”). It became impossible to type “DataBind” in Visual Studio without VB autocorrecting to “Databind.”

Most of the time, this didn’t matter an awful lot. However, when you do the following, you discover another one of those situations where VB helps you create behavior that is totally incomprehensible to and unfixable by your average VB programmer.

Public Class SomeCtrl
    Inherits Control

    Public Overrides Sub Databind()
        ' do something fancy
    End Sub
End Class

' ...

Public Sub Test()
    Dim C As Control = New SomeCtrl
    C.DataBind()
End Sub

For us, that C.DataBind was calling the DataBind method in System.Web.UI.Control! The reason can be found in Reflector:

VB.NET compilation bug

Visual Basic was actually creating a NEW virtual method with the lowercase b. It was NOT overriding DataBind. Despite the overrides keyword, which I guess is just a compiler feature and not a CLR construct (the virtual in MSIL covers everything).

We fixed our issue by opening up scores of .vb files in emacs, updating them to have the uppercase B, and then by deleting all of the files in %systemroot%\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\ on all of our dev machines and our build machine.

Is this yet another artifact of an extremely large VB solution? I have no idea, but to me, compiler bugs are very scary.

Attributes, WithEvents, and Backing Fields

Grahn Modulary in Kokomo, Indiana writes:

Why is only ‘booya’ printed out when Derived.Reflect() is called in this test program (below)? Shouldn’t I also get ‘raiser?’ What gives, Tito?

[Note, I omitted the ReflectMeAttribute and EventRaiser classes for clarity, they're not important].

Public Class Base

    <ReflectMe()> Protected WithEvents raiser As EventRaiser
    <ReflectMe()> Protected booya As String

    Protected asdf As String

    ' ...
End Class

Public Class Derived
    Inherits Base

    ''' <summary>
    ''' Prints out the name of all members marked with the ReflectMe() attribute.
    ''' </summary>
    Public Shared Sub Reflect()
       Dim members() As MemberInfo = GetType(Derived).GetMembers( _
           BindingFlags.NonPublic _
           Or BindingFlags.Public Or BindingFlags.Instance)

        For i As Integer = 0 To members.Length - 1
            If members(i).IsDefined(GetType(ReflectMeAttribute), True) Then
                Console.WriteLine(members(i).Name)
            End If
        Next
    End Function
End Class

Well Grahn, first of all, don’t call me “Tito.” Second, notice that if you move the Reflect method to the Base class, you’ll get two items back, but maybe not the ones you’d expect. You’ll get a private field called “_raiser.”

The problem originates with the use of the WithEvents keyword and the way it is handled by the VB compiler. The raiser field is replaced by a property of the same name, and a private backing field that together make the WithEvents work. The attribute is applied to the private field.

It’s a problem here because attributes will no longer work when inheritance is involved. You could possibly get around this if it were possible to target attributes in VB, but it’s not. This might fix it, as long as the attribute supports property targets:

<Property: ReflectMe()>

But currently the only attribute target you can specify this way in VB is Assembly.

Your example makes this look kind of lame, but one place this has bitten me in real code is in Page classes. When the ASP.NET 1.1 engine compiles a page, it derives from your codebehind class, thereby obscuring any private backing fields. It really gets crazy when you consider that the VS2003 designer will stick “WithEvents” on pretty much every field it generates, regardless of whether or not you use its functionality.

Where this REALLY becomes a problem is when you dabble in developing an attribute-based framework system for a web application (as I have). Unless your developers are way above average, you’ll find yourself struggling to explain this early and often.

I understand that there are some changes to the way that pages are compiled in ASP 2.0 that would fix this situation, but to me it’s not attacking the real problem. If anyone sees this, let me know if you’re aware of an elegant way around it that I haven’t thought of.