Skip to main content

Kris Vandermotten

Go Search
Kris Vandermotten
U2U Website
  

Kris.NET

  U2U Home
  U2U Course Calendar
Kris.NET
Source Analysis for C# (StyleCop) released

There have been rumors for years about a tool called StyleCop, used internally within Microsoft. According to the rumors, it was comparable to FxCop (Code Analysis), but would do its job at the source level (instead of the IL level used by FxCop). That way it would be able to check consistency of code style, you know, where to put spaces and comments and line breaks and stuff.

StyleCop, or Source Analysis as they call it now, has finally been released, and it turns out the rumors were true. It's a Visual Studio Add-In, that sits nicely in the project menu, right below Code Analysis.

Source Analysis

As you can imagine, the rules caused a lot of debate. The thing is, everybody can understand that it's a good idea not to declare protected members in sealed types (for example), but matters of style can't be debated rationally. After all, it's a matter of taste, or is it not?

As I've said before, "I hate it when developers have to make choices like that during routine development. Choosing takes time, and that's not likely to improve productivity. But much worse is the fact that different developers will make different choices. Even a single developer may make different choices from one day to the next. That leads to inconsistencies in the code. Developers will spend more time trying to understand the code they're reading, because it doesn't always follow the same pattern. That's bad for productivity. In the worst case scenario, developers start rewriting each other's code, just so it matches their choice of the day. That kills productivity."

So no, it's not a matter of style, it's all about productivity. What your standard is doesn't matter, what matters is that you have a standard, and that people follow it without wasting time.

So naturally, I took Source Analysis for a test drive on a bunch of code I have written. First impression: lots and lots of warnings! But many do return, so I made just a few setting changes:

Microsoft Source Analysis Project Settings

Only a handful of warnings remained, and to be honest, they had a point. It wasn't much, but my code improved thanks to this tool. And this was just my own code. The real value of a tool like this lies in the consistency it can bring to team projects, ending all pointless debates and holy wars about personal preferences.

The XML based file headers are clearly a Microsoft internal thing. But hey, if you want a copyright notice in every file, you might just as well do it this way. Remember, having a standard is important, which one it is doesn't matter (much).

Conclusion: very good addition to the toolbox, highly recommended.

.NET 3.5 SP1 Beta available

I have mentioned before that a CLR update is due to be released this summer.

Scott Guthrie just announced that a beta is now available. On the CLR, he says:

.NET 3.5 SP1 includes significant performance improvements to the CLR that enable much faster application startup times - in particular with "cold start" scenarios (where no .NET application is already running).  Much of these gains were achieved by changing the layout of blocks within CLR NGEN images, and by significantly optimizing disk IO access patterns.  We also made some nice optimizations to our JIT code generator that allow much better inlining of methods that utilize structs.

We are today measuring up to 40% faster application startup improvements for large .NET client applications with SP1 installed.  These optimizations also have the nice side-effect of improving ASP.NET application request per second throughput by up to 10% in some cases.

It's not just an update to the CLR though, it's a significant service pack to both the .NET Framework and Visual Studio 2008. Another novelty I'm definitely going to take a look at is Linq to Entities:

.NET 3.5 SP1 includes the new ADO.NET Entity Framework, which allows developers to define a higher-level Entity Data Model over their relational data, and then program in terms of this model.  Concepts like inheritance, complex types and relationships (including M:M support) can be modeled using it.

The ADO.NET Entity Framework and the VS 2008 Entity Framework Designer both support a pluggable provider model that allows them to be used with any database (including Oracle, DB2, MySql, PostgreSQL, SQLite, VistaDB, Informix, Sybase, and others).

Developers can then use LINQ and LINQ to Entities to query, manipulate, and update these entity objects.

Having fun with Linq to Nullable types

In C#, the following function compiles:

static double? Add(double? x, double? y)
{
    return x + y;
}

Event though there is no addition operator defined for double?, or for Nullable<T> in general. But the C# compiler translates the above to:

static double? Add(double? x, double? y)
{
   return x.HasValue && y.HasValue ? new double?(x.GetValueOrDefault() + y.GetValueOrDefault()) : null;
}

But I cannot write the following:

static double? Abs(double? x)
{
    return Math.Abs(x); // won't compile
}

With a bit of Linq though, I can write the following:

static double? Abs(double? x)
{
    return from d in x select Math.Abs(d);
}

All I need to make this work is the following extension method:

public static T? Select<T>(this T? x, Func<T, T> selector)
    where T : struct
{
    return x.HasValue ? new T?(selector(x.Value)) : null;
}

I could even add a Where extension method:

public static T? Where<T>(this T? source, Func<T, bool> predicate)
    where T : struct
{
    return source.HasValue && predicate(source.Value) ? source : null;
}

Which would allow weird (or cool?) stuff such as:

static double? Asin(double? x)
{
    return from d in x where d >= -1 && d <= 1 select Math.Asin(d);
}

Toss in a SelectMany:

public static V? SelectMany<T, U, V>(this T? source, Func<T, U?> k, Func<T, U, V> resultSelector)
    where T : struct
    where U : struct
    where V : struct
{
    if (k == null)
    {
        throw new ArgumentNullException("k");
    }
    if (resultSelector == null)
    {
        throw new ArgumentNullException("resultSelector");
    }
    return source.HasValue && k(source.Value).HasValue ? 
        new V?(resultSelector(source.Value, k(source.Value).Value)) : null;
}

And now I can write:

static double? SinCos(double? x, double? y)
{
    return from xd in x
           from yd in y
           select Math.Sin(xd) * Math.Cos(yd);
}

Who said Linq was about object-relational mappers? Or was it functional programming perhaps?

Technorati tags: , , ,
AssemblyInfo updated

AssemblyInfo, my Reflector plug-in, has been updated.

The new version lists all native and P/Invoke imports, and native exports. Access these features from the context menu of any module (native or managed). And there are a few minor bug fixes in the decompilation of generic members.

Get it from my download page.

Technorati tags: ,
PaintDotNetEffects updated for Paint.NET 3.30

My framework for Paint.NET effects, and the 13 effects, have been updated for Paint.NET 3.30.

You'll need Paint.NET 3.30 Beta 2 for these to work.

What's new:

  • Drop Shadow effect now has a color picker, as have the duotone and monochrome adjustments
  • The behavior of the sliders in several effect dialogs has been improved
  • The framework has support for some of the new features of Paint.NET 3.30
  • The icon for the Drop Shadow is back to the white circle (not that it really matters, but anyway)

Download the latest version, with full source code, from my download page.

Effects per DLL:

  • Vandermotten.PaintDotNetEffects.dll: You allways need this dll. It includes the framework used by the other dll's.
  • Vandermotten.PaintDotNetEffects.Blurs.dll: "Average Blur" and "Smart Blur" effects, under the Blurs effect menu.
  • Vandermotten.PaintDotNetEffects.DropShadow.dll: The "Drop Shadow" effect, under the Stylize effect menu. With offset, widening, blur and a color picker.
  • Vandermotten.PaintDotNetEffects.Duotones.dll: "Duotone Light" and "Duotone Ink on Paper" adjustments. Two color pickers for each.
  • Vandermotten.PaintDotNetEffects.FadeEdge.dll: "Fade Edge" effect, under the Photo effect menu.
  • Vandermotten.PaintDotNetEffects.Monochromes.dll: "Cyanotype", "Sepia 2", "Grayscale on Colored Paper" and "Monochrome Ink on Paper" adjustments. Did I mention the color pickers yet?
  • Vandermotten.PaintDotNetEffects.Samples.dll: You probably don't want these, unless you're looking at the source code. "Darken", "Lighten" and "Negative" adjustments.
Lightweight Code Generation with Linq Expressions

Linq expressions are the key ingredient behind the IQueryable<T> interface. One aspect of them, largely underestimated if you ask me, is the fact they can be compiled into executable code at runtime.

Let's look at a concrete example: a generic comparer, which compares objects based on one of their properties. Take a Person class, with a Name property (amongst others), and you want to sort a List<Person> by Name. Sure, if you statically know, at compile time that is, the property on which to sort, you can simply use the Linq orderby operator and pass it the Lambda to extract the property value. But what if you don't know the property statically? What if you need to be able to sort any type on any of its properties?

In that case you need a way to extract the property dynamically. Reflection can do the job, but it's slow. With Reflection.Emit you can generate a DynamicMethod, but Expressions provide an easier alternative.

The function I need will have three parameters:

var x = Expression.Parameter(typeof(TObject), "x");
var y = Expression.Parameter(typeof(TObject), "y");
var c = Expression.Parameter(typeof(IComparer<TProperty>), "c");

Given a PropertyInfo (or just a name) for the property, I can generate and expression for the function and compile it:

compare = Expression.Lambda<Func<TObject, TObject, IComparer<TProperty>, int>>
    (
        Expression.Call(
            c,
            "Compare", null,
            Expression.Property(x, propertyInfo),
            Expression.Property(y, propertyInfo)),
        x, y, c
    ).Compile();

That's really all there is to it. I can then wrap this function into an IComparer<TObject>, as shown below.

Why bother? Sure, generation of the comparer will take its fair share of CPU cycles. But execution of the comparer will be a lot faster. When I need to sort, say, 10 objects, it doesn't matter, that will be done quickly enough either way. But when I need to sort thousands of objects, this technique can offer a significant speedup.

And what alternatives do I have? I could use DynamicMethod, which is what I used to do before .NET 3.5. In fact, that's exactly what the Compile() method on an expression is doing. The generated function would be no different, but the generation code definitely is more difficult and error prone to write. Both options share the fact that I'm doing a delegate call for every comparison. I could get rid of that delegate call by generating a full assembly using Reflection.Emit. But then I need to worry about memory leaks, because I can't unload the assembly.

Expressions aren't as powerful as the raw DynamicMethod, but they're easier to use. That's why I prefer them over DynamicMethod whenever I can.

Full source code for the example, including a SortedBindingList<T> that uses PropertyComparer<T>:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;

namespace Vandermotten.Collections.Generic
{
    public class PropertyComparer<TObject>
    {
        public static IComparer<TObject> Create(string propertyName)
        {
            return Create(propertyName, ListSortDirection.Ascending);
        }

        public static IComparer<TObject> Create(string propertyName, ListSortDirection direction)
        {
            return Create(typeof(TObject).GetProperty(propertyName), direction);
        }

        public static IComparer<TObject> Create(PropertyInfo propertyInfo)
        {
            return Create(propertyInfo, ListSortDirection.Ascending);
        }

        public static IComparer<TObject> Create(PropertyInfo propertyInfo, ListSortDirection direction)
        {
            if (propertyInfo == null)
            {
                throw new ArgumentNullException("propertyInfo");
            }
            if (!propertyInfo.CanRead)
            {
                throw new ArgumentException("Cannot read property " + propertyInfo.Name);
            }
            Type cT = typeof(Comp<>).MakeGenericType(typeof(TObject), propertyInfo.PropertyType);
            return (IComparer<TObject>)Activator.CreateInstance(cT, propertyInfo, direction);
        }

        private class Comp<TProperty> : IComparer<TObject>
        {
            private Comparer<TProperty> comparer;

            public Comp(PropertyInfo propertyInfo, ListSortDirection direction)
            {
                comparer = Comparer<TProperty>.Default;

                var x = Expression.Parameter(typeof(TObject), "x");
                var y = Expression.Parameter(typeof(TObject), "y");
                var c = Expression.Parameter(typeof(IComparer<TProperty>), "c");

                if (direction == ListSortDirection.Ascending)
                {
                    compare = Expression.Lambda<Func<TObject, TObject, IComparer<TProperty>, int>>
                        (
                            Expression.Call(
                                c,
                                "Compare", null,
                                Expression.Property(x, propertyInfo),
                                Expression.Property(y, propertyInfo)),
                            x, y, c
                        ).Compile();
                }
                else
                {
                    compare = Expression.Lambda<Func<TObject, TObject, IComparer<TProperty>, int>>
                        (
                            Expression.Call(
                                c,
                                "Compare", null,
                                Expression.Property(y, propertyInfo),
                                Expression.Property(x, propertyInfo)),
                            x, y, c
                        ).Compile();
                }
            }

            Func<TObject, TObject, IComparer<TProperty>, int> compare;

            public int Compare(TObject x, TObject y)
            {
                return compare(x, y, comparer);
            }
        }
    }
    public class SortedBindingList<T> : BindingList<T>
    {
        private bool sorted;
        private ListSortDirection sortDirection = ListSortDirection.Ascending;
        private PropertyDescriptor sortProperty;

        public SortedBindingList()
        {
        }
        
        public SortedBindingList(List<T> list)
            : base (list)
        {
        }

        protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
        {
            List<T> items = Items as List<T>;
            if (items != null)
            {
                sortDirection = direction;
                sortProperty = prop;
                IComparer<T> pc = PropertyComparer<T>.Create(prop.Name, direction);
                items.Sort(pc);
                sorted = true;
            }
            else
            {
                sorted = false;
            }
        }

        protected override void RemoveSortCore()
        {
            sorted = false;
        }

        protected override bool SupportsSortingCore
        {
            get { return true; }
        }

        protected override bool IsSortedCore
        {
            get { return sorted; }
        }

        protected override ListSortDirection SortDirectionCore
        {
            get { return sortDirection; }
        }

        protected override PropertyDescriptor SortPropertyCore
        {
            get { return sortProperty; }
        }
    }
}
CLR Update this summer

On his blog, Scott Guthrie announced that an update for the .NET CLR will be released this summer:

This summer we are going to ship a servicing update to the CLR that makes some significant internal optimizations in how we optimize our data structures to cut down on disk IO and improve memory layout when loading and running applications. Among many other benefits, this work will significantly improve the working set and cold startup performance of .NET 2.0, 3.0 and 3.5 applications and will dramatically improve end-user experiences with .NET-based client applications.

Depending on the size of the application, we expect .NET applications to realize a cold startup performance improvement of between 25-40%. Applications do not need to change any code, nor be recompiled, in order to take advantage of these improvements so the benefits are automatic.

Free improvements are always good improvements. I do hope this update will include the optimizations on value types the JIT team has been blogging about:

Code generation for value types in .NET 2.0 has several inefficiencies.

1) All value type local variables live entirely on the stack.

2) No assertion propagation optimization is ever performed on value type local variables.

3) Methods with value type arguments, local variables, or return values are never inlined.

[...]

Over the past year or so, the JIT team has been working on significant improvements to value type code generation, as well as the inlining algorithm. In summary, all of the above limitations are being eliminated.

AssemblyInfo and Paint.NET Effects Updated

There's a bug fix for AssemblyInfo, my .NET Reflector language plug-in. The type name of generic types now renders correctly.

There's also a new version of the Paint.NET effects I released only two days ago. I got quite some feedback from the Paint.NET user community. I've split the framework from the demo's, and I split the demo's into 6 separate dll's. That makes it easier for Paint.NET users to choose which effects they want to install. And the effects now show up in the standard localized menu's. Last but not least, there's a small but important optimization in the Drop Shadow effect.

Both can be downloaded from my download page.

13 Paint.NET Effects and a Framework to create your own

I've created 13 "new" Paint.NET effects (9 adjustments and 4 effects) and a framework to create your own effects more easily. Download Vandermotten.PaintDotNetEffects from my download page. Full source code is included in the download.

The nine adjustments are:

  • Cyanotype: the classical blueprint look, see http://en.wikipedia.org/wiki/Cyanotype. This actually is a demonstration of the Monochrome Ink on Paper adjustment, see below.
  • Darken: darkens an image, simple demo of the framework. See also below.
  • Lighten: lightens an image, simple demo of the framework.
  • Duotone Ink on Paper: see http://en.wikipedia.org/wiki/Duotone. Set the two ink colors using the Colors window.
  • Duotone Light: a variation on the traditional duotone, where two colored light sources are mixed additively. Set the two light colors using the colors window.
  • Grayscale on Colored Paper: well, it looks like a grayscale image on colored paper :-). Set the paper color using the colors window. Or maybe it's a black and white image projected with a colored light...
  • Monochrome Ink on Paper: looks like a grayscale image printed with one color ink. Set the ink color using the colors window.
  • Negative: duplicate of the built-in Invert Colors adjustment, provided as a very simple demo of the framework. See also below.
  • Sepia: simple demo of the Grayscale on Colored Paper adjustment, configurable though.

And four effects:

  • Drop Shadow: creates a drop shadow under an image with transparency. Offset, widening and shadow blur can be controlled. The widening option also allows creating outlines around images. Shadow color is set using the colors window before starting the effect.
  • Fade Edge: a simple demo of the framework. Fades the edge of an image. Width and power can be controlled.
  • Average Blur: averages all pixels within a controlled radius.
  • Smart Blur: averages pixels in a controlled radius if their color is close enough to the center color. This is very useful to reduce aliasing from scanned prints, especially of cartoon-like images.

So how do you create an effect with the framework? Let's starts with a very simple adjustment example: negative. An adjustment processes one pixel at a time, where one color is transformed into another color, no matter where the color appeared in the original image. In essence, an adjustment is a function that takes one color parameter, and returns another one.

public delegate ColorBgra Adjustment(ColorBgra source);

To create a Paint.NET adjustment effect, create a dll project and add references to PaintDotNet.Base, PaintDotNet.Core, PaintDotNet.Effects, and ... Vandermotten.PaintDotNetEffects. Create a class inheriting from Vandermotten.PaintDotNetEffects.SmartAdjustment:

using PaintDotNet;
using PaintDotNet.Effects; using Vandermotten.PaintDotNetEffects; [EffectCategory(EffectCategory.Adjustment)] public class NegativeAdjustment : SmartAdjustment { public NegativeAdjustment() : base("Negative") { } protected override Adjustment AdjustmentToRender { get { return c => new ColorBgra() { B = (byte)(255 - c.B), G = (byte)(255 - c.G), R = (byte)(255 - c.R), A = c.A }; } } }

Attribute the class with the EffectCategory attribute, to make it appear under the adjustments menu. In the constructor, call the base constructor to set a name, and optionally an icon, submenu and effect flags. All you need to do now is override the AdjustmentToRender property. Return a function that transforms one color into another and you're done.

Notice also how easy it becomes to unit test your adjustments. Just call the function returned by AdjustmentToRender from your unit tests and validate the results.

And what about configurable adjustments, such as Darken? Rick has made developing configurable effects much easier than it used to be, but SmartProperties go one step further:

[EffectCategory(EffectCategory.Adjustment)]
public class DarkenAdjustment : SmartAdjustment
{
    public DarkenAdjustment()
        : base("Darken", null, EffectFlags.Configurable)
    {
    }

    SmartDoubleProperty factor = new SmartDoubleProperty("Factor")
    {
        DefaultValue = 1.5,
        MinValue = 1,
        MaxValue = 16
    };

    protected override IEnumerable<ISmartProperty> GetProperties()
    {
        return new ISmartProperty[] { factor };
    }

    protected override Adjustment AdjustmentToRender
    {
        get
        {
            if (factor == 1)
            {
                return c => c;
            }
            return c => new ColorBgra()
            {
                B = (byte)(c.B / factor),
                G = (byte)(c.G / factor),
                R = (byte)(c.R / factor),
                A = c.A
            };
        }
    }
}

Tell the base class the effect is configurable, declare and initialize the properties (of type double, int or bool for now), and override GetProperties(). You can then use those properties in your AdjustmentToRender implementation.

Notice how AdjustmentToRender varies the function it returns by the values of the configuration properties. This is a key aspect of the functional programming style: this basic form of partial evaluation becomes almost trivially easy to implement, and can yield important performance benefits. In fact, the Drop Shadow effect in the download can be terribly slow for certain image and parameter combinations, but this partial evaluation, combined with the lazy evaluation of some parts of the function, make it perform very fast in most cases.

Non-adjustment effects work similarly to adjustments, but there are some very important differences as well. More about those in a later post. Or take a look at the source code that's included in the download. You'll need Visual Studio 2008 to compile it, but you can use the framework from Visual Studio 2005 as well (though you'll miss the convenient C# 3.0 syntax).

Enjoy.

.NET Framework Library Source Code now available

See the announcement on Scott Guthrie's blog. See setup instructions on Shawn Burke's Blog.

1 - 10 Next

 ‭(Hidden)‬ Admin Links