You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using BinaryWriter.Write(string), it attempts to optimize the performance, and when the value is short enough (and the encoding is UTF8), then the operation may bypass the Write7BitEncodedInt call.
But this is a problem if we use a derived BinaryWriter where the Write(int) method is overridden because the Write7BitEncodedInt method calls the virtual Write(int) method.
Example: we have a pair of reader-writer that dumps the written/read values while adjusts the current position. Since BinaryReaderalways calls the Read7BitEncodedInt method, the dumped information and offsets slowly drift away when short strings are written:
Reproduction Steps
Create a derived BinaryWriter with an overridden Write(int) method.
Call Write(string) with various lengths
Observe that the overridden Write(int) is sometimes called, sometimes not, depending on string length.
Expected behavior
BinaryWriter and BinaryReader should have a symmetric behavior. When we have a derived BinaryWriter class, I always expect the overridden Write(int) method to be called because that's how BinaryReader also works (ie. its ReadString always calls ReadInt32).
Actual behavior
BinaryWriter.Write(string) sometimes calls the implicit Write(int) method, sometimes not. See the details above.
Regression?
It works in .NET Framework, and it worked in .NET 5.0.
Known Workarounds
Duplicating the old behavior in a derived class without calling base.Write(string) (a bit painful).
Configuration
Noticed in .NET 9 Preview 7 but it turns out that we have this behavior since .NET 6.0
Other information
Possible solutions:
Check in the base constructor if the current type is a derived one, and if so, then initialize the _useFastUtf8 field to false.
Or, allow only the "semi-optimized" branch, which still calls the Write7BitEncodedInt method,
Activity
dotnet-policy-service commentedon Sep 2, 2024
Tagging subscribers to this area: @dotnet/area-system-io
See info in area-owners.md if you want to be subscribed.
jozkee commentedon Sep 3, 2024
Possibly related to #47316.
BinaryWriter: fixing Write(string) for derived types. Fixes dotnet#10…
koszeggy commentedon Sep 4, 2024
I created a pull request.
jeffhandley commentedon Feb 9, 2025
Assigned to @adamsitnik for the necessary further triage, along with consideration of the #107369 PR.
Thank you for your efforts and patience on this, @koszeggy.
BinaryWriter tests: checking derived reader/writer behavior (dotnet#1…
Binary writer fix (#107369)