Archive for the ‘.NET’ Category

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.

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.

HttpModule for Performing a Custom Action for Certain Urls

I wrote this collection of classes over the holidays as part of a side project and forgot about it. Today at work I needed basically exactly the same thing, but unfortunately I didn’t have it handy and had to recreate it from scratch.

This is a way to execute any action you please for requests against url’s matching one or more regular expressions. Today at work, I used it to install a response filter for a specific set of .aspx pages. I can think of at least a few more reasons someone might want something like this, so I’m posting it.

using System;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Collections;
using System.Web;

namespace McKinley.Web
{
    /// <summary>
    /// An abstract <see cref="T:System.Web.IHttpModule"/> that checks
    /// the url of each incoming request against one or more regular
    /// expressions. When a match is found, a custom action is
    /// performed.
    /// </summary>
    public abstract class BaseRegexModule : IHttpModule
    {
        private RegexChain _chain;

        /// <summary>
        /// Reads the list of regular expressions to match from
        /// the configuration settings. Hooks the beginning of
        /// each request to perform the checks.
        /// </summary>
        public void Init(HttpApplication context)
        {
            Hashtable settings = (Hashtable)ConfigurationSettings.GetConfig(this.ConfigSectionName);
            if(settings != null)
            {
                _chain = new RegexChain();
                foreach(object val in settings.Keys)
                {
                    string pattern = val as string;
                    if(pattern != null && pattern.Length > 0)
                    {
                        _chain.Add(pattern);
                    }
                    else
                    {
                        throw new ConfigurationException(
                            "The regular expression pattern may not be empty.");
                    }
                }
            }
            context.BeginRequest += new EventHandler(BeginRequest);
        }

        /// <summary>
        /// Tries to match the raw url against the list of expressions
        /// given to the module. If a match is found, calls the abstract
        /// <see cref="M:CustomAction"/> method.
        /// </summary>
        private void BeginRequest(object sender, EventArgs e)
        {
            HttpApplication application = sender as HttpApplication;
            if(application != null)
            {
                HttpRequest request = application.Request;
                if(request != null && _chain.IsMatch(request.RawUrl))
                {
                    CustomAction(application);
                }
            }
        }

        /// <summary>
        /// This must be overridden to provide the name of the configuration
        /// section for the concrete module class. The section is presumed
        /// to use a <see cref="T:System.Configuration.DictionarySectionHandler"/>.
        /// </summary>
        protected abstract string ConfigSectionName { get; }

        /// <summary>
        /// This must be overridden to define a custom action to be performed
        /// when one of the regular expressions are matched against the
        /// request's URL.
        /// </summary>
        protected abstract void CustomAction(HttpApplication context);

        public void Dispose() { }

        public BaseRegexModule() { }
    }

    /// <summary>
    /// This is an efficient utility class for a list of
    /// regular expressions evaluated together.
    /// </summary>
    internal class RegexChain
    {
        private class Node
        {
            public Regex Expression;
            public Node Next;

            public Node(Regex r)
            {
                Expression = r;
            }
         }

        private Node _head;
        private Node _tail;

        /// <summary>
        /// Returns true if the given string is a match
        /// for any of the regular expressions in the chain.
        /// </summary>
        public bool IsMatch(string input)
        {
            Node n = _head;
            while(n != null)
            {
                if(n.Expression.IsMatch(input))
                {
                    return true;
                }
                n = n.Next;
            }
            return false;
        }

        /// <summary>
        /// Adds the given pattern to the chain of regular
        /// expressions.
        /// </summary>
        public void Add(string pattern)
        {
            Node n = new Node(new Regex(pattern));
            if(_head == null)
            {
                _head = n;
            }
            else
            {
                _tail.Next = n;
            }
            _tail = n;
        }
    }

    /// <summary>
    /// This is a <see cref="T:System.Configuration.IConfigurationSectionHandler"/>
    /// that can be used with a class derived from
    /// <see cref="T:McKinley.Web.BaseRegexModule"/>.
    /// </summary>
    public class RegexModuleSectionHandler : DictionarySectionHandler
    {
        protected override string KeyAttributeName
        {
            get { return "pattern"; }
        }
    }
}

And there you have it. Here’s an extremely simple example class that uses this to set a cookie for matching url’s.

public class ExampleRegexModule : BaseRegexModule
{
    public ExampleRegexModule() { }

    protected override void CustomAction(System.Web.HttpApplication context)
    {
        context.Response.AppendCookie(new HttpCookie("Oscar", "Is god"));
    }

    protected override string ConfigSectionName
    {
        get { return "mckinley.web/exampleRegexModule"; }
    }
}

And finally, here are the web.config entries you’d need to install this HttpModule.

<configSections>
    <sectionGroup name="mckinley.web">
        <section
            name="exampleRegexModule"
            type="McKinley.Web.RegexModuleSectionHandler, McKinley.Web"
        />
    </sectionGroup>
</configSections>

<mckinley.web>
    <exampleRegexModule>
        <add pattern="somepage.aspx" />
    </exampleRegexModule>
</mckinley.web>

<system.web>
    <httpModules>
        <add name="example"
                type="McKinley.Web.ExampleRegexModule, McKinley.Web" />
    </httpModules>
<system.web>

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

.NET Math Quiz

I’ve been having a lot of fun with this post on .NET Undocumented.

If x, y, z are ints, …

1. If x < 0, then -x > 0.

False, unchecked(-int.MinValue) == int.MinValue.

2. If x = -x, then x = 0.

False (see 1)

3. If x - y > 0, then x > y.

False, unchecked(int.MinValue - int.MaxValue) == 1

4. If x and y are positive, then x + y > x.

False, unchecked(int.MaxValue + 1) < int.MaxValue

5. If x and y are positive, then (double)x * (double)y = (long)x * (long)y.

True – I don’t think this can’t be broken over the range of the integers. Not so over the longs, though.

6. If x - y > 0 and y - z > 0, then x - z > 0.

False, use

int x = int.MaxValue-1;

int y = -1;

int z = int.MinValue;

This gives you x - y == int.MaxValue, y - z == int.MaxValue, and x - z == -1.


If x, y, z are doubles, …

1. x = x.

False. double.NaN != double.NaN.

2. If x > y is false, then x < = y is true.

False – use double.NaN for both.

3. If x > 0, then x - x = 0.

False. double.PositiveInfinity - double.PositiveInfinity == double.NaN

4. If x and y are positive integers, then x + y > x.

This is true because at the boundary condition, double.MaxValue + double.MaxValue == double.PositiveInfinity.

Note that this is different from the behavior of longs or ints. It is only true for integer doubles, though, because x + double.Epsilon == x.

5. If x and y are integers and x > 0, then the statement “x + y = x for all y” is false for all x.

True.

6. If x <= 0 is false, then x > 0.

Both statements are false for double.NaN.

7. If x and y are longs, then (double)(x + y) = (long)(x + y).

This is true because of the order of operations, but it does not hold for (double)x + (double)y.

8. if x.Equals(y), then x = y.

This is false for double.NaN.

9. If x.Equals(-x), then x = 0.

This is false for double.NaN.

10. if x.ComparesTo(y) < 0, then x < y.

This is false where x is double.NaN.

Note: You don’t need to use the unchecked keyword for the counterexamples using it to be valid; it is easy enough to come up with examples that will pass as long as runtime checks are off. I just used it so that my answers would be brief and would compile.

The VB Compiler and Late Binding

Something interesting I came across today. Two seemingly identical loops in two different languages:

for(int i = 0; i <= 10000000; i++)
{
    TimeSpan t2 = DateTime.Now.Subtract(t);
    // assume we do something more interesting in
    // a real program...
}
Dim t As DateTime = DateTime.Now()
For i As Integer = 0 To 10000000
    Dim t2 As TimeSpan = Now.Subtract(t)
    ' assume we do something more interesting in a
    ' real program...
    t2 = Nothing
Next

There is a difference, obviously—the VB programmer has attempted to set the TimeSpan t2 (a ValueType) to Nothing. The VB compiler doesn’t prohibit you from doing this, as the C# compiler would if that programmer had tried to set t2 = null.

Programmers at my company (other than me) do this constantly. The reason is that they got used to doing it to every object variable in VB6. Whether or not that was actually necessary, I don’t know. It’s beyond the scope of this post, anyway.

At any rate, it shouldn’t matter. At most, it should end up just being one instruction and might even get tossed out by the JIT compiler. Right? Wrong.

On average, the C# loop executes more than 5 times faster. Roughly 5 seconds for VB versus roughly one second for C# on my machine. When you remove the extra line in VB, the times are comparable. If we replace TimeSpan with a reference type but leave the extra line, the times are comparable.

Why? Looking at the MSIL generated when we have gives us this in Release mode:

; Equivalent to GetType(TimeSpan)
L_001d: ldtoken [mscorlib]System.TimeSpan
L_0022: call [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle([mscorlib]System.RuntimeTypeHandle)

; This is the late-binding way of creating an empty TimeSpan.
L_0027: call object [mscorlib]System.Activator::CreateInstance([mscorlib]System.Type)
L_002c: unbox [mscorlib]System.TimeSpan
L_0031: ldobj [mscorlib]System.TimeSpan
L_0036: stloc.2

Ok, so I can see now what the compiler is trying to do. Whereas the C# compiler would make us explicitly go looking for the TimeSpan.Zero field if we wanted to reset the value of a variable, the VB compiler is trying to help us out by creating an empty structure for us.

It would have saved us a little trouble, if that was at all what we were intending to do. In my case, it just happened because a cargo-cult programmer is used to typing it. Another problem is that it happens where, even understanding this behavior, you would still not expect it. Consider:

' Reminder - DictionaryEntry is a struct.
For Each entry As DictionaryEntry In hash
    ' ...
Next

This ends up being equivalent to setting entry = Nothing with each iteration. You’d therefore get the same late binding IL and this loop is many times slower than the “same” loop in C#.

I’m not a language or compiler designer, but here’s what I would like to see done (in order of preference).

  1. Disallow this with Option Strict On, like C# does currently (a breaking change, obviously).
  2. Give a compiler warning where it will happen.
  3. Do a better job of publicizing this kind of behavior. I can’t find any documentation on it.

String.Join Equivalent for Any List of Objects

Something that has been bugging me for a while is that there is no framework function as simple as string.Join( ) for, say, an array of integers. Or at least, there aren’t any that I’m aware of.

There are a bunch of ways to write this, of course, but I like this implementation using custom formatters that I’ve made most of all. It’s obviously not the most efficient way to do it, but I find it extremely useful.

// First, the class that is used as the public interface.
// This provides an object that does the heavy lifting.
public class EnumerableFormatProvider : IFormatProvider
{
    private static EnumerableFormatter _formatter =
        new EnumerableFormatter();

    private static EnumerableFormatProvider _default =
        new EnumerableFormatProvider();

    public static EnumerableFormatProvider Default
    {
        get { return _default; }
    }

    public object GetFormat(Type formatType)
    {
        if (formatType == typeof(ICustomFormatter))
        {
            return _formatter;
        }
        return null;
    }

    private EnumerableFormatProvider() { }
}

// Now the class that enumerates the objects and joins them up.
internal class EnumerableFormatter : ICustomFormatter
{
    public EnumerableFormatter() { }

    public string Format(string format, object arg,
                         IFormatProvider formatProvider)
    {
        if (arg == null)
        {
            return string.Empty;
        }

        IEnumerable e = arg as IEnumerable;
        if (e == null)
        {
            return arg.ToString();
        }
        else
        {
            StringBuilder sb = new StringBuilder();
            bool first = true;

            IEnumerator en = e.GetEnumerator();
            while (en.MoveNext())
            {
                if (!first)
                {
                    sb.Append(format);
                }
                first = false;
                sb.Append(en.Current.ToString());
            }
            return sb.ToString();
         }
    }
}

Here’s one example of how you might use it.

static void Main(string[] args)
{
    // prints "1234"
    Console.WriteLine(
        string.Format(EnumerableFormatProvider.Default, "{0}",
        new int[] { 1, 2, 3, 4 })
    );

    // prints "1,2,3,4"
    Console.WriteLine(
        string.Format(EnumerableFormatProvider.Default, "{0:,}",
        new int[] { 1, 2, 3, 4 })
    );
}

FxCop and Guidelines

Brad Abram’s Designing Good Libraries post inspired me to find out if some of the trickier rules mentioned are already caught by FxCop. Obviously many of the casing and naming guidelines are covered.

This code:

private static string[] _privArray = { "a", "b", "c" };

/// <summary>
/// We should not return the static array here,
/// as the elements can be changed by the caller.
/// </summary>
public string[] GetStrings()
{
    return _privArray;
}

Is not caught, but this code:

/// <summary>
/// We should not expose a static array like this,
/// because the elements can be changed.
/// </summary>
public static readonly char[] InvalidPathChars = { '\"', '<', '>' };

Is found with this message:

Either replace TheClassFromHell.InvalidPathChars with a strongly typed collection that cannot be changed, or replace the public field with a method that returns a clone of a private array.

It seems like it would be pretty easy to adapt that rule to cover the getter method example. Perhaps I’ll add that to my Festivus-vacation to-do list.

This code isn’t caught either, but it seems like it would be more difficult to find.

/// <summary>
/// The function should return an empty array instead
/// of a null array.
/// </summary>
public string[] GetStringsNull(bool a)
{
    if (a)
    {
        return new string[] { "a", "b" };
    }
    return null;
}

Man, I love FxCop. Partially because of moments like this:

Correct the spelling of the unrecognized token 'Sucky' in namespace 'SuckyLibrary'.

But mostly because it is more efficient and less stressful than reiterating standards ad nauseum.

On the same topic, I was wondering about this:

Using Structs

  • What happens?

    MyStruct[] arr = new MyStruct[10];

  • The constructor for MyStruct is not run here
  • Do not provide a default constructor

It seems to me as if it’s not possible to create a default (parameterless) public constructor for a struct – at least not in C# anyway. Maybe this restriction is not part of the CLR, or maybe we’re talking about constructors with parameters?

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.