How to create extension methods?

Dynamic currying: part 3

Is said to in Europe, every man has an average of omega replica three watches, and to pay attention to the instrument famous Italy the average man watch has reached eight, these watches can mix and match clothing, to cope with a variety of uk replica watches occasions need. Here we are not talking about the fashion of men in Italy wear what table, but to explore the famous British Agent 007 James Bond in the film wearing what table. Isn't James Bond fashionable? The answer is obviously negative. Rolex Rolex, Omega and Seiko, is the most popular 007 favored brand, these brands period alternating from one side reflects the development path of rolex uk brand watches, and watch the performance in the film also a good interpretation of the brand connotation and the personality. ROLEX Rolex, OMEGA OMEGA and SEIKO precision, is the most popular brand of 007

In the last post, it looked like we are done. We created the DOM and it compiled nicely to a library. But calling the methods could be nicer. Right now, it's like this:


Wouldn't it be great, if we could call it like this:


That's exactly what extension methods are for. Just make the class static and add the this keyword. Except both of these are C#-specific. And as I mentioned last time, CodeDOM tries to be language-agnostic, so it doesn't support this.

Isn't there anything we can do? There is a way … But we have to get our hands dirty and use string manipulation. Last time, we were creating the library directly from DOM. But we can convert the DOM to a string containing the C# code, modify that the way we need and then compile the code into a library:

var writer = new StringWriter();

var provider = new CSharpCodeProvider();

    compileUnit, writer, new CodeGeneratorOptions { BracingStyle = "C" });

string code = writer.ToString();

code = code.Replace("class FuncExtensions", "static class FuncExtensions");
code = code.Replace("(Func<", "(this Func<");

    new CompilerParameters(new[] { "System.Core.dll" }, "Currying.dll") { GenerateInMemory = false },

The string manipulation code is actually quite simple, but it's fragile. If we wanted to change what we do, we would have to check every time that it's still doing what we want.

Now that we finally have everything we wanted, let's be a little curious: how does the code generated from all those lambdas look like? Horribly.

The lambda for Func with 15 parameters results in 15 different closure classes, nested one inside another. And each of the other lambdas has its own hierarchy. What's worse, every class has references to all its predecessors. This looks quite wasteful, memory-wise, but it saves time that would be otherwise required to get all the parameters.

If I was doing this by hand, I would probably always pass the parameters gathered so far to the next closure class. But this is only possible, because I know the closure is no mutated in any way.

This finishes this series. See you next time.

codedom dotnet c#
Posted by: Petr Onderka
Last revised: 03 Dec, 2016 07:36 PM History


25 Jul, 2011 03:49 AM

I found my way here from stackoverflow. I have a dynamic curry implementation too but using the DLR. It proxies based on DynamicObject and dynamic convert itself into being wrapped by a static delegate type to if you cast it. Not as performant as writing a bunch of functions sensibly, but works for all sorts of other things you might want to curry like methods or other dynamic objects that couldn't be done sensibly.

Func<int, int, int, int, int> add = (x, y, z, bbq) => x + y + z +bbq;  //Original function
Func<int, Func<int, Func<int, Func<int, int>>>> curry0 = Impromptu.Curry(add); // curry and then implicit cast
var curry1 = curry0(4);
var curry2 = curry1(5);
var curry3 = curry2(6);
var result = curry3(20); //35!
26 Jul, 2011 08:07 PM

Yeah, I noticed that while I was looking at your source code because of that question.

Your version is certainly interesting too, but I don't like the fact that it's dynamic. Yeah, you can cast the result into the (quite ugly) delegate type, but that's not checked statically. Although dynamic has its uses, I prefer doing things statically most of the time.

Another thing is that the main purpose of this series for me was to learn CodeDOM, which looks like a cool technology (as a much more user-friendly alternative to Reflection.Emit). Currying was just an interesting topic to facilitate that.

Your Comments

Used for your gravatar. Not required. Will not be public.
Posting code? Indent it by four spaces to make it look nice. Learn more about Markdown.