dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
19.04k stars 4.03k forks source link

Documentation on C# code to Expression conversion logic/quirks #42045

Open MaceWindu opened 4 years ago

MaceWindu commented 4 years ago

Guys, is it possible to provide some kind of documentation on what changes C# compiler applies to expression tree when it generates Expression object from C# code in IQueryable context?

As ORM developers, who need to work with expressions, from time to time we hit issues, because we receive unexpected values from expressions. Like char or enum values is source code being replaced with integer constants in generated Expression. This is not a problem to implement proper handling of such cases if we aware of them, but without any documentation on this behavior, right now it is more like minefield - you find out each new case by accident.

Just several issues for reference:

AndriySvyryd commented 3 years ago

Take a look at https://github.com/bartdesmet/csharplang/blob/ExpressionTypes/spec/conversions.md, it contains some proposed clarifications

MaceWindu commented 3 years ago

looking at https://github.com/bartdesmet/csharplang/commit/22813d644547773b25bfb0b918d224220b7b0f58#diff-a9bc6b564a697de274db9d836517d0431bbfbd770b658a6edd13edfbaf27ec7c changes it is hard to say how it makes it more clear. But after reading document in general I think I have some ideas what's going on on expression build:

Maybe those changes to expression tree should be clear from spec, but I think it will make sense to list them explicitly...

MaceWindu commented 3 years ago

Another case of conversion we discovered:

default(T) operator replaced with corresponding ExpressionConstant which resulted in error for users, that use non-compiler generated expressions (in our case by OData library) because we missed DefaultExpression handling