Implementation of anonymous delegates in C#

What is the output of the following program?

int x = 5;

Action action = (() => { Console.WriteLine(x); });

x = 6;

action();



The output is of course 6, because delegates capture references to outer variables.

So how is this implemented in the compiler?
The compiler rewrites the code above to something like this:

Scope s = new Scope();

scope.x = 5;

Action action = (scope);

scope.x = 6;

scope.Call();


and defines the Scope class like this:

private sealed class Scope

{

    public int x;

 

    public Scope();

    public void Call()

    {

        Console.WriteLine(this.x);

    }

}



As we would expect, the is no way to create a reference to eg. an int in IL, so this is solved naturally - the int is wrapped inside Scope class and all accesses are done through the wrapper.
The wrapper also defines the Call method, which is exactly the body of the anonymous delegate.

Actually, the compiler generated name for our Scope class is "<>__DisplayClass1", and the Call method is named "<Main>b__0".

For a little more complex example, see this post on stackoverflow.

Posted by Martin Konicek on 4:18 PM 0 comments

HTTPS and DNS poisoning attack

The best explanation of HTTPS I have seen was written by Jeff Moser, highly recommended!

After reading the article, there was only one thing left unclear, so I asked the author, Jeff Moser, and he responded:

Me:


Just one thing is really unclear to me - DNS poisoning: The attacker obtains certificate from amazon.com, I enter "amazon.com" to browser, browser goes to attacker's site, which responds by valid amazon.com certificate signed by Verisign. How does the browser tell this is an attack?


Jeff:

Great question! Note that if an attacker did this, they'd run into trouble in the "Trading Secrets" section that I described. Without knowing Amazon.com's private key, they couldn't decrypt the pre-master secret that the client sends out because the certificate from Verisign has Amazon's public key. Thus, the client would use that public key (and not one an attacker generated).


DNS poisoning is an attack when attacker fools DNS server. You type "amazon.com" in the browser, the browser asks the DNS server to resolve the URL = to translate the URL to IP address. Since the DNS server is poisoned, it returns attacker's IP address and browser connects to attacker's server, while address bar reads "amazon.com" - quite nasty.

Now everything is 100% clear, thanks Jeff!

Posted by Martin Konicek on 2:08 AM 0 comments

Custom IFormatProvider for doubles

The following example shows how to write a custom IFormatProvider which you can use in String.Format(IFormatProvider, ...).

public class DoubleFormatter : IFormatProvider, ICustomFormatter

{

    // always use dot separator for doubles

    private CultureInfo enUsCulture =

        CultureInfo.GetCultureInfo("en-US");

 

    public string Format(string format, object arg,

                            IFormatProvider formatProvider)

    {

        // format doubles to 3 decimal places

        return string.Format(enUsCulture, "{0:0.000}", arg);

    }

 

    public object GetFormat(Type formatType)

    {

        return (formatType == typeof(ICustomFormatter))

            ? this : null;

    }

}



Having this formatter, we can use it like this:

double width = 15.77555;

double height = 12.8497979;

Console.WriteLine(

    string.Format(new DoubleFormatter(), "w={0} h={1}", width, height));



Output:

w=15.776 h=12.850



So now we have a reusable format for doubles - 3 decimal places with dot separator. That is nice, but this formatter is very simple - it formats everything (eg. DateTime) as "0:000". This is a fast version if you know that you will only use it for formatting lots of doubles.

The real version should look like this:

public class DoubleFormatter : IFormatProvider, ICustomFormatter

{

    // always use dot separator for doubles

    private CultureInfo enUsCulture =

        CultureInfo.GetCultureInfo("en-US");

 

    public string Format(string format, object arg,

                        IFormatProvider formatProvider)

    {

        if (arg is double)

        {

            if (string.IsNullOrEmpty(format))

            {

                // by default, format doubles to 3 decimal places

                return string.Format(enUsCulture, "{0:0.000}", arg);

            }

            else

            {

                // if user supplied own format use it

                return ((double)arg).ToString(format, enUsCulture);

            }

        }

        // format everything else normally

        if (arg is IFormattable)

            return ((IFormattable)arg).ToString(format, formatProvider);

        else return arg.ToString();

    }

 

    public object GetFormat(Type formatType)

    {

        return (formatType == typeof(ICustomFormatter)) ? this : null;

    }

}



Example:

Console.WriteLine(string.Format(new DoubleFormatter(),

    "Numbers {0} and {1:0.0}." +

    "Now a string {2}, a number {3}, date {4} and object: {5}",

    1.234567, -0.57123456, "Hi!", 5, DateTime.Now, new object()));



Output:

Numbers 1.235 and -0.6. Now a string Hi!, a number 5, date 12.6.2009 17:11:35 and object: System.Object



This article should give you an overview of implementing custom IFormatProvider. Now you should be able to modify the code to suit your specific needs.

Other examples with custom formatters can be found in MSDN. See example with formatter for 12-digit account numbers (12345–678–9012).

Posted by Martin Konicek on 2:02 PM 1 comments

Associating data with an event

I just solved the following problem - best explained by concrete example:

WPF Animation.Completed is an event. I need to register this event and when it fires, access custom data associated with the event:

void animate(Graph graph)

{

    PointAnimation anim = new PointAnimation();

    anim.Completed += new EventHandler(anim_Completed);

 

    // in anim_Completed, I want to call graph.Fix() - how?

}

 

void anim_Completed(object sender, EventArgs e)

{

    // how do I access 'graph' here?

}



Seems like a tough problem. Remembering 'graph' in eg. static variable is not an option, especially if we have more graphs animated at the same time.
Fortunately, C#'s lambdas come to the rescue:

void animate(Graph graph)

{

    PointAnimation anim = new PointAnimation();

    anim.Completed += new EventHandler((s, e) => { graph.Fix(); });

}



This works because anonymous methods bind to outer variables.

Posted by Martin Konicek on 2:55 PM 0 comments

Starting with Scala - slides from presentation

I started learning Scala programming language.

Scala rocks! It is statically typed, has functional features, and aims for developer productivity. In Scala you can express what you want with less code than in C#. Scala runs on JVM and any Java code can be called from Scala.

Here are the slides from my presentation at Charles University in Prague:     pdf, powerpoint, examples (.zip)

Some of Scala's clever concepts suprised me:

  • Actors - a totally different thinking about concurrency than you are used to. No threads + shared state + locks. Actors live independently, share no state, and communicate by sending each other messages.
  • Adding new keywords to the language just by writing ordinary methods. Consider adding C#'s using or lock keyword to Scala, without compiler support!
  • Traits - behaviors can be mixed in freely at instatiation time, sort of built-in Strategy design pattern.
  • Absence of the static keyword, turns out it is not needed! Instead of having static state and methods of a class, you declare a singleton instance and call its methods.

If you want to see concrete examples, check out the slides.. it's coding time ;)

Links to get started:
First steps to Scala - a great tutorial.
Twitter on Scala - detailed interview - did you know that Twitter runs on Scala?

Thanks to my friends Joe and Pz for support!

Posted by Martin Konicek on 12:21 AM 3 comments

I'm in!

Great news! I've been accepted to Google summer of code. I'll be working on debugger visualizers for SharpDevelop.
This is a great opportunity to continue my work on the Object graph visualizer, and even get it integrated in an open source IDE.
I'll be also working on other visualizers and things (particularly one of them totally cool in my opinion).
Cool thing about this is that none of the visualizers is present in Visual Studio.
Hope the visualizers will make your debugging experience even better :)

Posted by Martin Konicek on 11:52 AM 1 comments

Debugger Visualizer for Visual Studio

Recently, I have been playing with implementing a Visual Studio add-in that displays your data structures as graphs live as you debug.



The graph on the right shows current state of the data structure being watched. The graph updates as you step through the code.
Here is an example of more complex structure:



The layout is done using GLEE graph layout engine, which could be possibly replaced by Graphviz or something else.

As I was suspecting prior to the implementation, there is an important issue that needs to be solved: when the user does a step in the debugger, the object graph is rebuilt from scratch and the layout engine calculates new layout. However, even if the graph changes only slightly, it can sometimes affect the layout significantly and therefore confuse the user.
I am currently thinking about matching nodes from current step to the nodes from the previous step (provided the graph doesn't change that much between steps, which is typically true - and when it chages too much, we don't mind layout changes anyway). The matching of the two graphs could be used to preserve the layout until the nodes really have to move. And if they have to move, move them in a way that they preserve relative positions to each other. There is a space for some interesting algorithms here.

Current source code of the add-in is available here.

Posted by Martin Konicek on 3:01 PM 4 comments