Category: .NET

Expressions aren’t made equal

I got surprised by Expressions last week while trying to create a caching mechanism for them. To be precise, this piece of code

static void Main()
{
    Expression<Action<string>> first = s => Console.WriteLine(s);
    Expression<Action<string>> second = n => Console.WriteLine(n);
    Expression<Action<string>> third = n => Console.WriteLine(n);
    Check(first, second);
    Check(second, third);
 
}
 
private static void Check(Expression<Action<string>> a, Expression<Action<string>> b)
{
    Console.WriteLine("{0} (hc: {1})\nis {2}equal to \n{3} (hc: {4})\n-------------",
                      a, a.GetHashCode(),
                      (a.Equals(b) ? "" : "not "),
                      b, b.GetHashCode());
}

Produces this result

Expressions

which I find… well, not intuitive.

Expression (and classes deriving from it) do not override Equals and GetHashCode, so we get standard System.Object behavior. I really can see no reason why it works this way. Expressions denote piece of algorithm, so one might expect two semantically identical Expressions to be equal (and to have the same hashcode). I would actually expect first and second expressions to be equal. They aren’t equal syntactically (first’s parameter is called “s” and second’s parameter is called “n”, so they are different in this regard). Semantically thought they are identical, so why aren’t they equal?

The good news is, that you can create your own IComparer<Expression> and implement that behavior. The bad news is, you have to do it. I’d be thankful if someone pointed me to some explanation why it’s done this way.

Microoptimizations: foreach vs for in C#

Patrick Smacchia wrote a post where he compares execution time while using different patterns to iterate over a collection, namely List<int> and int[]. Since he provided the code, I decided to give it a go as well. Only thing I did, was I added [MethodImpl(MethodImplOptions.NoInlining)] for each method, since they all were very simple, and could easily be inlined.

That said, here are my results (release build ran without debugger, outside of Visual Studio):

iterate

If you compare those to Patrick’s results, you may notice few things:

  • Patrick has a faster PC (which only reminds me I really should start looking for a new one)
  • When you turn off inlining results are much different. First, foreach is as efficient on arrays as on lists (which is different than Patrick’s results. My guess is, that since CLR has more intimate knowledge of arrays, it somehow optimized it when inlining was turned on).
  • iterating with for loop is faster when you do the trick Patrick called “count optimization”. This is quite the contrary to what Eric Gunnerson said, and I’m puzzled about it.
  • DO NOT all go and change your foreaching code to for loops! The numbers you see are number of ticks when iterating over a collection of 100 000 000 elements! That means that in each and every case, iteration is fast as hell, and it’s NOT your bottleneck. To help you visualize that, here’s a picture I borrowed from K. Scott Allen

Delegate.CreateDelegate exception with proxies

While playing with dynamic invocation of WCF proxies I found a strange behavior with Delegate.CreateDelegate method.

It throws exception when trying to create delegate for WCF proxy method.

The following sample code causes the ArgumentException with message “Error binding to target method.”

 

        private static void Main()
        {                 
            var proxy = new DuplexChannelFactory<IMyService>(
                new InstanceContext(new MyServiceCallback()),
                "myService").CreateChannel();
            var method = proxy.GetType().GetMethod("MyOperationWithCallback");
            Debug.Assert(method != null);
            Action<IEnumerable<MyParameter>> action = proxy.MyOperationWithCallback;
            Debug.Assert(action != null);
            var d = Delegate.CreateDelegate(typeof(Action<IEnumerable<MyParameter>>), proxy, method);
        }

exception

It’s really annoying, and looks like a bug in the BCL. My workaround, was to build LINQ expression, and compile it into delegate. It however requires .NET 3.5.

.NET 4.0 and Visual Studio 2010

I’m downloading .NET 4.0 and Visual Studio 2010. Currently it looks like  this:

vs2010

It looks like I will have to wait till tomorrow to play with partial local types, dynamic objects, and whatever Anders is announcing right in this very moment.

Good night.

Skip generated types when performing analysis in NDepend

Code created in more recent versions of C# has a lot of generated types, even if you don’t use code generation explicitly. Interators (the yield keyword), and anonymous delegates both use generated types underneath. Also those neat anonymous types introduced in C# 3.0 are nothing more than a compiler magic.

All this may clutter your NDepend window of choice, when looking at your projects. You can however get rid of generated stuff, pretty easily, with this simple CQL query:

// <Name>Types not generated by the compiler</Name>
SELECT TYPES FROM ASSEMBLIES "YourAssembly" 
WHERE !(HasAttribute "System.Runtime.CompilerServices.CompilerGeneratedAttribute")

Simple, but useful.

If you want to get rid of just some types of generated classes, for example you want to get rid of iterators, but want to leave anonymous delegate classes, you may use regular expressions for that. This is my clumsy attempt to that:

// <Name>Types not generated by the compiler</Name>
SELECT TYPES FROM ASSEMBLIES "Castle.Facilities.WcfIntegration" WHERE 
!NameLike ".+<>c__.+" /* Anonymous delegates, like private sealed class <>c__DisplayClass1
*/ AND 
!NameLike ".+\+<.*>d__.+" /* Iterators, like private sealed class <FindDependencies>d__0<T> :
IEnumerable<T>, IEnumerable, IEnumerator<T>, IEnumerator, IDisposable */

Technorati Tags: , ,

Slower than Reflection; meet StackTrace

I was entertaining the idea of contextual components that would act differently depending on who called them. System.Diagnostics.StackTrace is the class that allows you to traverse the call stack, and see who called your method. There’s one catch though – it is painfully slow. And by painfully, I mean this:

StackTrace

Those two methods are by no means comparable in regard of what they’re doing. They are mere examples of simple tasks: one involving Reflection, and one involving StackTrace. The fact that the difference in performance is nearly two orders of magnitude, should make you think twice before you go down the StackTrace path. Especially considering the fact, that you can’t really cache it.

Technorati Tags: , ,

Remove assemblies from Dependency Graph in NDepend

Last minor version of NDepend introduced cool, interactive Dependency Graph, that was really a huge step forward as compared to static .png we got earlier. You can now load set of assemblies, and immediately see dependencies between them, without running your_picture_viewer_here. You also can drill down the dependency tree  and see dependencies between namespaces within an assembly, classes within namespace, methods within class…

One thing (ok, there are more, but we’ll get to that in a minute), that I missed, was the ability to remove an element from the graph. You could do this using CQL, but this just was too complicated solution. This is now possible with new and fresh 2.10.3 build.

Remove element from NDepend' Dependency Graph

So, back to my wishlist. You can interact with only one element of the graph at any given moment. That means, although you can select few assembles with ctrl+LMB if you click Remove, only one will get removed. Same with drilling down. You can’t select few assembles and go “View internal dependency cycles on graph” to see cycles between classes in all of those assemblies. (well, you can as a matter of fact do this with CQL, but again, this may require a lot of typing and GUI just feels like the right place to do it.)

Second thing I wish it had, is a scrollbar for zooming instead of + / – buttons. Can we get this Partick?

Technorati Tags: ,

Framework Tips XI: What is this?

Lately while going through the code of latest MEF release, I stumbled upon a piece of code that used a very little known feature of .NET

Just take a look:

public struct Tuple<TFirst, TSecond>
{
    public Tuple(TFirst first, TSecond second)
    {
        this = new Tuple<TFirst, TSecond>();//looks strange?
        this.First = first;
        this.Second = second;
    }
    //[...]
}

I myself was shocked at first. “Hey! You can’t assign to this! It’s against the nature and common sense.” Then I went to C# language specification to look for explanation and indeed I’ve found it.

The key here is the fact that Tuple is a struct, not a class. As it turns out, the meaning of this differs between those two.

The explanation comes from chapter 11.3.6 – Meaning of this


Within an instance constructor or instance function member of a class, this is classified as a value. Thus, while this can be used to refer to the instance for which the function member was invoked, it is not possible to assign to this in a function member of a class.

Within an instance constructor of a struct, this corresponds to an out parameter of the struct type, and within an instance function member of a struct, this corresponds to a ref parameter of the struct type. In both cases, this is classified as a variable, and it is possible to modify the entire struct for which the function member was invoked by assigning to this or by passing this as a ref or out parameter.

It makes total sense when you think about it, still – I think many experienced people can be surprised by that.

Technorati Tags:

AnkhSVN 2.0 – Visual Studio SVN integration reinvented

Along with Subversion 1.5 and TortoiseSVN 1.5 a new version of AnkhSVN has been released some time ago.

AnkhSVN_Solution_Explorer

AnkhSVN v1.x used to suffer from many issues. It was instable, used far too much resources, and had many usability bugs, that repelled many people. For version 2.0 many parts of the tool have been rewritten from ground up, and now it’s a very descent tool that you should give second chance if you abandoned it after trying out previous version.

I was very pleasantly surprised by it, when I fired up my Visual Studio today, and I saw this:

AnkhSVN

Geee, now it even checks for updates, cool.

Good stuff. If you passed on it before, you definitely should give it another try – really, new version is a whole other tool.

Free ebook: “Foundation of Programming” (the ALT.NET way)

Karl Seguin, has created, and made available for free and ebook, called “Foundation of Programming”. Don’t be fooled by its name however. If you’re thinking, “Foundation? I’m a senior level developer, what possibly could I learn from a foundation book?” and intend to pass by it, think again.

The topic range spreads from Domain Driven Development, Persistence, Dependency Injection, Unit Testing, Mocking, Object/Relational Mapping to Memory Management, Exceptions and Proxies. Looks like a solid weekend read.

Thanks a lot Karl!