-
Notifications
You must be signed in to change notification settings - Fork 832
Closed
Description
When i create an anonymous record, the fields get sorted by name.
This cause issues when libraries expect the same order of declaration.
An example in dapper
// dotnet add package Dapper
open Dapper
// docker pull mcr.microsoft.com/mssql/server:2017-latest-ubuntu
// docker run -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=<YourStrong!Passw0rd>" -p 1433:1433 --name sql1 -d mcr.microsoft.com/mssql/server:2017-latest-ubuntu
let connection = @"Data Source=localhost,1433;Database=master;User=sa;Password=<YourStrong!Passw0rd>;";
use db = new SqlConnection(connection)
db.Open()
// OK, same order
let res = db.QuerySingle<{|Name: string; Tid: int; X:string; Y: int|}>("select Name='fdsf', Tid=20, X='hfds', Y=15")
// fails but understandable, different order
let res = db.QuerySingle<{|Name: string; Tid: int; X:string; Y: int|}>("select Tid=20, Name='fdsf', X='hfds', Y=15")
// fails and unexpected, same order
let res = db.QuerySingle<{|Tid: int; Name: string; X:string; Y: int|}>("select Tid=20, Name='fdsf', X='hfds', Y=15") the error is cryptic too, but explain it doesnt find the constructor with right shape
Unhandled Exception: System.InvalidOperationException: A parameterless default constructor or one matching signature (System.Int32 Tid, System.String Name, System.String X, System.Int32 Y) is required for <>f__AnonymousType1611086028`4'[[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int32, System.Private.CoreLib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]] materialization
Repro steps
Use the snippet above.
We can also compare C# and F#
// F#
let x = {| Tid = 20; Name = "fdsf"; X = "hfds"; Y = 15 |}
// IL
IL_00ea: ldstr "fdsf"
IL_00ef: ldc.i4.s 20 // 0x14
IL_00f1: ldstr "hfds"
IL_00f6: ldc.i4.s 15 // 0x0f
IL_00f8: newobj instance void class '<>f__AnonymousType1611086028`4\''<string, int32, string, int32>::.ctor(!0/*string*/, !1/*int32*/, !2/*string*/, !3/*int32*/)
while C#
// C#
var x = new { Tid = 20, Name = "fdsf", X = "hfds", Y = 15 };
// IL
IL_0001: ldc.i4.s 20 // 0x14
IL_0003: ldstr "fdsf"
IL_0008: ldstr "hfds"
IL_000d: ldc.i4.s 15 // 0x0f
IL_000f: newobj instance void class '<>f__AnonymousType0`4'<int32, string, string, int32>::.ctor(!0/*int32*/, !1/*string*/, !2/*string*/, !3/*int32*/)```
Expected behavior
The generated IL respect order of declaration
Actual behavior
The generated IL sort the field names
Known workarounds
None
Related information
> dotnet --info
.NET Core SDK (reflecting any global.json):
Version: 3.0.100-preview3-010431
Commit: d72abce213
Runtime Environment:
OS Name: Windows
OS Version: 10.0.17134
OS Platform: Windows
RID: win10-x64
Host (useful for support):
Version: 3.0.0-preview3-27503-5
Commit: 3844df9537
0x53A, rodrigovidal, s952163, callmekohei and jannikbuschke
Metadata
Metadata
Assignees
Labels
No labels