Occasionally inconsistent order of Serializer.GetProto<FooEnum>() in .NET 6 and earlier versions
#1,102 opened on Oct 16, 2023
Repository metrics
- Stars
- (4,426 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
When running Serializer.GetProto<FooEnum>() in .NET 3.1 and .NET 6.0, the order of the returned string is occasionally inconsistent except for the leading 0.
Given a FooEnum
using ProtoBuf;
namespace Bar
{
[ProtoContract]
public enum FooEnum
{
[ProtoEnum]
A,
[ProtoEnum]
B,
[ProtoEnum]
C,
}
}
After running Serializer.GetProto<FooEnum>(), the expected protobuf is
syntax = "proto3";
package Bar;
enum FooEnum {
A = 0;
B = 1;
C = 2;
}
However, it occasionally be
syntax = "proto3";
package Bar;
enum FooEnum {
A = 0;
C = 2;
B = 1;
}
I tested with a FooEnum with 17 members, the inconsistent order occurred 1 out of 183, 705, 715, 1004, 705 runs. The inconsistent order might be caused by
- Get MemberInfo[] by System.Type.GetMembers() in MetaType.cs
- Write enum members sequentially in MetaType.cs
According to the definition of Type.GetMembers()
In .NET 6 and earlier versions, the GetMembers method does not return members in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which members are returned, because that order varies. However, starting with .NET 7, the ordering is deterministic based upon the metadata ordering in the assembly.
When I deliberately alter the sequence of MemberInfo[] retrieved from Type.GetMembers() in my forked branch, the disorder becomes consistently reproducible.