@@ -43,7 +43,9 @@ module ExtraTopLevelOperators =
4343[<DebuggerDisplay( " Count = {Count}" ) >]
4444[<DebuggerTypeProxy( typedefof< DictDebugView<_,_,_>>) >]
4545type DictImpl < 'SafeKey , 'Key , 'T >( t :Dictionary < 'SafeKey , 'T >, makeSafeKey : 'Key -> 'SafeKey , getKey : 'SafeKey -> 'Key ) =
46-
46+ #if NETSTANDARD
47+ static let emptyEnumerator = ( Array.empty< KeyValuePair< 'Key, 'T>> :> seq<_>) .GetEnumerator()
48+ #endif
4749member x.Count = t.Count
4850
4951// Give a read-only view of the dictionary
@@ -110,8 +112,34 @@ module ExtraTopLevelOperators =
110112member s.GetEnumerator () =
111113// We use an array comprehension here instead of seq {} as otherwise we get incorrect
112114// IEnumerator.Reset() and IEnumerator.Current semantics.
115+ // Coreclr has a bug with SZGenericEnumerators --- implement a correct enumerator. On desktop use the desktop implementation because it's ngened.
116+ #if ! NETSTANDARD
113117let kvps = [| for ( KeyValue( k, v)) in t-> KeyValuePair( getKey k, v) |] :> seq<_>
114118 kvps.GetEnumerator()
119+ #else
120+ let endIndex = t.Count
121+ if endIndex= 0 then emptyEnumerator
122+ else
123+ let kvps = [| for ( KeyValue( k, v)) in t-> KeyValuePair( getKey k, v) |]
124+ let mutable index = - 1
125+ let current () =
126+ if index< 0 then raise<| InvalidOperationException( SR.GetString( SR.enumerationNotStarted))
127+ if index>= endIndexthen raise<| InvalidOperationException( SR.GetString( SR.enumerationAlreadyFinished))
128+ kvps.[ index]
129+
130+ { new IEnumerator<_> with
131+ member __.Current = current()
132+ interface System.Collections.IEnumeratorwith
133+ member __.Current = box( current())
134+ member __.MoveNext () =
135+ if index< endIndexthen
136+ index<- index+ 1
137+ index< endIndex
138+ else false
139+ member __.Reset () = index<- - 1
140+ interface System.IDisposablewith
141+ member self.Dispose () = () }
142+ #endif
115143
116144interface System.Collections.IEnumerablewith
117145member s.GetEnumerator () =