Welcome to irritatedVowel.com Sign in | Help

POKE 53280,0: Pete Brown's Blog

Silverlight, WPF, Woodworking, .NET Programming, CNC, Nature, and other topics.

Pete Brown writes on a number of topics including Silverlight, WPF, .NET, woodworking and working as a consultant in the DC area. On most forums, Pete goes by the name Psychlist1972. Pete has worked at Applied Information Sciences (AIS) since 1996 where he currently performs as a lead architect and project manager.

Subscribe to my feed

Add to Technorati Favorites
Applied Information Sciences - My Employer

Community Events



World Domination

who's online

Networks


View Pete Brown's profile on LinkedIn

AddThis Social Bookmark Button

Extension Methods D'oh! Moment

image Sometimes you get so caught up in the complexity of an overall problem or solution, that you miss the simplest error even when it is staring you right in the face.

So, the other day, I was working on some c# code for a personal project I'll post here in a few weeks. In it, I needed to create a color based on HSL rather than RGB.

HSL is very useful when you want to generate a number of colors that all have similar characteristics: in this case, I wanted to generate a bunch of random colors all with the same saturation and brightness, but varying hues. Trying to do that in the RGB color space is next to impossible without doing some sort of HSL conversion.

I've built extension methods in the past, and have found them quite helpful in some situations. This sounded like a good use for extension methods, based on an algorithm I found, I built an extension to Color that took in the appropriate HSL values and set the R, G and B properties.

public static Color SetHsl(this Color color, double h, double s, double l)
{
    double r, g, b;
    // ...
    color.R = (byte)(255 * r);
    color.G = (byte)(255 * g);
    color.B = (byte)(255 * b);
    color.A = 255;
}

Now, some of you are likely looking at this code and nodding knowingly. Pat yourself on the back for catching that right away, as I killed a solid hour trying to figure out what on earth I did wrong :)

No matter what I did, the color was always black. It wasn't immediately obvious to me that it was black, because it was also transparent, and on the far end of a gradient.

First, I am not familiar with the math behind the HSL->RGB algorithm, so my first thought was that there was a bug in there. I spent a good chunk of time validating it and walking through it. Secondly, I thought maybe it was a platform bug (yes, we all blame the frameworks before our own code <g>).

The nature of the problem became clear to me when I copied the code over to a new project targeting a different platform (you have to love the .NET framework!) and got the same results.

Enough with the suspense. If you didn't catch the error right away, you're in good company. In the end, it is the absolute simplest first-day-of CS101 error you could make: Color is a struct. Structs are value types, and are passed as copies. So the code below always ended up with an initialized but not set color object - transparent black / #00000000 because the extension method was operating on a copy.

Color color = new Color();
color.SetHsl(rnd.Next(0, 10000) / 10000.0D, 0.75, 0.5);

So in C#, that means you can't have mutator extension methods on value types. That's a useful tidbit to keep in mind.

It turns out this is one place where VB actually has a leg up. In VB.NET, you can make the [me] parameter ByRef. C# doesn't allow ref this parameters in extension methods. (I've seen examples online as to why C# wouldn't allow this, mostly dealing with generic extension methods that could target value and reference types and therefore have unintended effects)

Sometimes it's the simplest stuff that snags us up on projects. :)

  Add to Technorati Favorites
Posted: Friday, February 22, 2008 11:27 AM by Pete.Brown
Filed under:

Comments

Reflective Perspective - Chris Alcock » The Morning Brew #39 said:

PingBack from http://blog.cwa.me.uk/2008/02/25/the-morning-brew-39/
# February 25, 2008 2:17 AM

Oskar Austegard said:

On a related, similar Duh, note: You can't create an extension method for a static class either since the extension method mechanism always expects an instance of the extended class....
# February 25, 2008 7:46 AM

AdamJTP said:

Ha - this just caught me out. I noticed that silverlight 2 had removed many of the Rect methods I had been using. I then tried re-creating them using extension methods.
# March 9, 2008 8:15 PM

Mike Brown said:

That was my first thought when I read the code. I guess there are two things that VB has on us C sharpers, this and the XML data types...although I'm seeing less utility to the latter.
# March 17, 2008 6:59 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the text you see in the image:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS