6

I have a solution with a bunch of projects, all running on .Net Standard 2.0 or .Net Core 2.2. Also due to historic reason in all project files the language version is defined as <LangVersion>latest<LangVersion>. Since one of the last Visual Studio updates (currently I'm on 16.3.7) also .Net Core 3.0 and C# 8 came available. So far so good.

Then as time passed by I implemented some functionality based on EF core (but that doesn't matter in this case) and wrote the following code (more or less):

var entity = _context.SomeEntities
    .Where(entity => entity.Id == id)
    .FirstOrDefault();

And it compiled without any problems! Where is the error message A local or parameter named 'item' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter?

Even the following code compiles without any errors:

var items = Enumerable.Range(1, 10);
var item = 2;
Console.WriteLine(item);
item = items.FirstOrDefault(item => item % 2 == 0);

I would guess the compiler picks the nearest variable and does what the programmer hopefully intended. Unfortunately I didn't find any information about that this is one of the new features of C# 8 and is allowed now. But I found some other (and older) posts like this discussion that it is better to let the compiler fail in these cases, cause it makes more trouble in the long shot and now this feature is simply gone.

So does anyone have some links or documentation about this specific new behaviour and if this is really intended and what are the reasons for the mind change?

Oliver
  • 43,366
  • 8
  • 94
  • 151
  • 2
    Intentional, this evolved from allowing shadowing for local functions: https://github.com/dotnet/csharplang/blob/master/meetings/2019/LDM-2019-01-16.md – Hans Passant Oct 31 '19 at 09:38
  • So the question "Allow shadowing for all lambdas?" and the short answer "Yes" within the linked document seems to explain why this is possible now. Nevertheless I'm a little curious that this will work now, cause I'm still a fan of the old behaviour, cause it simply helps to avoid awkward bugs. – Oliver Oct 31 '19 at 12:49
  • The answer is to search in the repo like Hans Passant did. You'll find discussions about shadowing as far back [as 2014](https://github.com/dotnet/csharplang/blob/98043cdc889303d956d540d7ab3bc4f5044a9d3b/meetings/2014/LDM-2014-09-03.md#removing-the-shadowing-restriction) if not earlier and *many* specific discussions since. You'll find issues that discuss the specific proposals that required lambda shadowing, eg [Champion "static local functions"](https://github.com/dotnet/csharplang/issues/1565). – Panagiotis Kanavos Oct 31 '19 at 13:22
  • Reading those discussions it seems a primary motivation was to *avoid* different shadowing behavior in different parts of the same program, if not the same method – Panagiotis Kanavos Oct 31 '19 at 13:23

0 Answers0