Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,026 | Comments: 44,844

filter by tags archive

Csc.exe and delegate inference, or: Why C# has awkward syntax

time to read 2 min | 212 words

I just tried to to do a major revamp of Rhino Mocks' interface. It was intended to make it easier to work with C# 3.0 and use the smarter compiler to get better syntax.

I shouldn't have bothered. Take a look at this.

	public class TestCsc
		public static void TestMethod()
			Execute(Bar); // fail to compile
			Execute(delegate(int ia, string x) { }); // compiles fine
			Execute((int i, string x) => { return; }); // Compiles fine
			Execute((int i, string x) => { return true; }); // fail to compile
			Execute(Foo);// fail to compile
			Execute(delegate(int ia, string x) { return true; }); // fail to compile

		public static bool Foo(int ia, string x)
			return false;

		public static void Bar(int ia, string x)

		public static void Execute<T, K>(Action<T, K> e)

		public static void Execute<T, K>(Func<bool, T, K> e)




Maybe you were looking for Func<T, K, bool>?


public static void Execute<T, K>(Func<bool, T, K> e)

should be

public static void Execute<T, K>(Func<T, K,bool> e)


after that there will be errors only with



you can rewrite this as

        Action<int, string> bar_ptr = Bar;

        Execute(bar_ptr); // compiles fine

        Func<int, string, bool> foo_ptr = Foo;

        Execute(foo_ptr);// compiles fine

Here is big explanation why type inference didn't work in this case:


But for me that was not very convincing.


Lambda stuff is nice but I would love to see Boo DSL for rhino mocks :)

Frans Bouma

Yes, this is pretty annoying. I ran into this as well when I wanted to introduce some types for prefetchpath specifications inside linq queries and wanted to get rid of the explicit generic argument specifications... IMHO it's a compiler flaw, no matter how many excuses they invent: they introduced syntactic sugar, then make the compiler deal with that in all cases.

Justin Etheredge

If you swap the bool on the end to Func<T, K, bool> then everything except for Execute(Bar) and Execute(Foo) works. And I agree with Frans, I have heard all the explanations about why it wouldn't work, but I wish they could have found a way to make it work.

Justin Etheredge

Let me also say that they could have enabled this for very simple scenarios such as the one you are dealing with. In the blog post by Eric Lippert referenced above he basically says that they could have done it in certain scenarios, but in other scenarios it would have been impossible. He said that they didn't want two different inference algorithms that produce slightly different results. While I am certainly not a compiler writer, that sounds like they are taking an idealistic approach and not a pragmatic one. The pragmatic approach would have been to try and make type inference work in as many different scenarios as possible, and have it fail when the resolution is unreachable.


Execute((t, k) => Bar(t, k));

Execute((t, k) => Foo(t, k));

Krzysztof Koźmic

I now your pain, earlier this week, I've been trying to come up with nicer, and more strongly typed ways to cope with events in Rhino.Mocks (strongly typed EventRaiser, event subscribtion and verification) and I failed miserably. I think I just gave up (at least for now). You can see the attempts at my blog.

And BTW, why are delegates so limited in cooperation with generics? :/ It's just annoying

Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats