27

Consider the following code:

var result = IDisposable.Dispose is object; //result equals false

It was surprise for me(and to my colleague that actually drew my attention to it) that this code is compiled.

First my thought was that IDisposable.Dispose is somehow converted to a compatible delegate. But then result must be true since delegate is compartible with object, of course.

Looking into the specification I found that method groups have special treating by the compiler(in the context of is operation):

If E is a method group ... the result is false.

Purely out of curiosity, why is it in the spec? Why does the compiler allow it? Why not to throw compile-time error (like for anonymous functions, for instance)?

UPDATE:

  • It compiled for me in VS2013 (12.0.21005.1) and .NET 4.5/4.5.1;
  • piojo let us know that this code is NOT compiled in Mono(I can't check it myself);
  • It is NOT compiled for leppie in VS2015(4.5 or 3.5);
  • NOT compiled under VS2013 / 12.0.30501.00 update 2, .NET 4.5.2 target(caramiriel);
Community
  • 1
  • 1
alekseevi15
  • 1,732
  • 2
  • 16
  • 20
  • 1
    Curiously, it actually doesn't compile on Mono. (At least, not my version.) – piojo Jan 19 '15 at 09:02
  • @piojo, thank you. I updated question with your note. – alekseevi15 Jan 19 '15 at 09:11
  • 1
    Does not compile for me on 4.5 or 3.5 in VS2015: `error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.` – leppie Jan 19 '15 at 09:18
  • 2
    In VS2010, it is only a warning: `warning CS0184: The given expression is never of the provided ('object') type` – leppie Jan 19 '15 at 09:20
  • 1
    Compiler even puts a `nop` and `0` (i4) on the stack in debug-mode, so it's not even ending up in the resulting assembly (VS2013 / 12.0.30501.00 update 2, .NET 4.5.2 target). – Caramiriel Jan 19 '15 at 09:21
  • 1
    In VS2013, it also gives a compiler error. I can only assume this was deemed a bug and the warning was changed to an error. I dont have VS2012 handy to test if this a warning or error. – leppie Jan 19 '15 at 09:22
  • 1
    Does compile on VS2013 and .Net 4.5.1. – Sjoerd222888 Jan 19 '15 at 09:25
  • 1
    It does compile on my end. I am using VS2012, .NET 4. I am only getting the warning: *The given expression is never of the provided ('object') type* – Giorgos Betsos Jan 19 '15 at 09:32
  • @Caramiriel: Same setup for VS2013 Update 2, targetting anything, compiler reports error. – leppie Jan 19 '15 at 09:41
  • Using ildasm on the .exe I only get: `.entrypoint .maxstack 8 ret`! – Giorgos Betsos Jan 19 '15 at 09:47
  • Related discussion by Jon Skeet back in 2006 on the matter: https://social.msdn.microsoft.com/Forums/en-US/7f6ac5f0-1c31-46c5-b965-99438fe374b8/cs0184-should-be-a-compile-error?forum=csharplanguage Note that method groups are not mentioned in the related MSDN document: http://msdn.microsoft.com/en-us/library/bb384251%28v=vs.90%29.aspx – Jeroen Vannevel Jan 19 '15 at 09:47
  • @leppie Does 2015 come with an updated spec that no longer says it should evaluate to false? – Rawling Jan 19 '15 at 09:47
  • 1
    you don't have to edit in all the individual comments in to your question. people can read the comments. – default Jan 19 '15 at 09:50
  • 1
    @Rawling: I have no idea. We should summon the language lawyers ;p – leppie Jan 19 '15 at 09:50
  • They targetted a `method group` specifically in the specs of the `is` operator? Wow. I wouldn't be suprised by a delegate, but a method group? I always thought `method groups` are only a tiny entity related to initialization of delegates. Why would anyone try to IS a MG? Please, can anyone enlighten me? One use case would be enough – quetzalcoatl Jan 19 '15 at 09:56
  • 1
    [Roslyn](http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.CSharp/Binder/Binder_Operators.cs,2562) doesn't provides many clues either, other than basically saying "it's in the spec"... although it does show the [switch to an error](http://source.roslyn.codeplex.com/#Microsoft.CodeAnalysis.CSharp/Binder/Binder_Operators.cs,2529) – Rhumborl Jan 19 '15 at 10:21
  • I believe it's clearly a bug. It can't be converted to any delegate type since you didn't specify any. the method signature might be compatible with more than one delegate. So.. – Selman Genç Jan 19 '15 at 10:45
  • 1
    It's not just specifically called out once in the spec; section 7.1 (Expression classifications) also explicitly calls out the three places where method groups are valid - including as the left hand side of an `is` - so it definitely looks *deliberate*. – Damien_The_Unbeliever Jan 19 '15 at 11:09
  • @Rhumborl weird that they haven't taken out the warning case now that the error case is in place. Also, I wish I could see whtat `DevDiv #864740` was :D – Rawling Jan 19 '15 at 11:25
  • @Damien_The_Unbeliever ,Rawling,well then clearly that spec is not up to date.Since it gives this compiler error on VS 2015 Preview, as stated in previous comments: _error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group._ – Selman Genç Jan 19 '15 at 11:26
  • 1
    @Selman22 Is there a C# 6.0 spec published yet? (BTW it's not *not up to date*, it's the *C# 5.0* spec. It's not going to go out of date.) – Rawling Jan 19 '15 at 11:26
  • @Rawling yes, it's C#5.0 spec. when the new spec is published it will go out of date. – Selman Genç Jan 19 '15 at 11:38
  • I can't find a 2.0 spec around at the moment; the 1.1 language spec doesn't allow this construct, but by version 3.0 it's been added - so it was added to the spec as part of either 2.0 or 3.0. – Damien_The_Unbeliever Jan 19 '15 at 11:38
  • 1
    @Selman22 - no, it will not go out of date. If, in ten years time, you want to construct a compiler that parses C# 5.0, that will be the spec to follow. – Damien_The_Unbeliever Jan 19 '15 at 11:39

0 Answers0