рдмрд░рд╛рдмрд░реА рдФрд░ GetHashCode рдУрд╡рд░рд░рд╛рдЗрдбрд┐рдВрдЧред рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рдпрд╣ рдЬрд░реВрд░реА рд╣реИ?

рдпрджрд┐ рдЖрдк C # рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ, рддреЛ рдЖрдк рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ GetHashCode рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ Equals , рд╕рд╛рде рд╣реА GetHashCode рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдЖрдЬ, рд╣рдо рджреЛ рдЯреНрдпреВрдирд┐рдВрдЧ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдгреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред



рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХрд┐рддрдиреА рдЧрдВрднреАрд░ рд╣реИ?


рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрднрд╛рд╡рд┐рдд рдкреНрд░рджрд░реНрд╢рди рд╕рдорд╕реНрдпрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреНрд░рдо рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИред Enum.HasFlag рд╡рд┐рдзрд┐ рдмрд╣реБрдд рдХреБрд╢рд▓ рдирд╣реАрдВ рд╣реИ (*), рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рдХреЛрдб рдХреЗ рдХреЛрдб рдкрд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХреЛрдИ рдЧрдВрднреАрд░ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрдЧреАред рдпрд╣ рдЧреИрд░-рдкрдардиреАрдп рд╕рдВрд░рдЪрдирд╛ рдкреНрд░рдХрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рддреИрдпрд╛рд░ рдХреА рдЧрдИ рд╕рдВрд░рдХреНрд╖рд┐рдд рдкреНрд░рддрд┐рдпреЛрдВ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рднреА рд╣реИред рд╕рдорд╕реНрдпрд╛ рдореМрдЬреВрдж рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред

(*) .NET рдХреЛрд░ 2.1 рдореЗрдВ рдлрд┐рдХреНрд╕реНрдб, рдФрд░, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдкрд┐рдЫрд▓реЗ рдкреНрд░рдХрд╛рд╢рди рдореЗрдВ рдмрддрд╛рдпрд╛ рдерд╛ , рдЕрдм рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡-рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдП рдЧрдП HasFlag рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдХрдо рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЖрдЬ рд╣рдо рдЬрд┐рд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рд╡рд╣ рд╡рд┐рд╢реЗрд╖ рд╣реИред рдпрджрд┐ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ Equals рдФрд░ GetHashCode рд╡рд┐рдзрд┐рдпрд╛рдБ рдирд╣реАрдВ рдмрдирд╛рдИ рдЧрдИ рд╣реИрдВ, рддреЛ System.ValueType рд╕реЗ рдЙрдирдХреЗ рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг System.ValueType ред рдФрд░ рд╡реЗ рдЕрдВрддрд┐рдо рдЖрд╡реЗрджрди рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдХрд╛рдлреА рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг рдзреАрдорд╛ рдХреНрдпреЛрдВ рд╣реИрдВ?


рд╕реАрдПрд▓рдЖрд░ рд▓реЗрдЦрдХреЛрдВ рдиреЗ рд╡реЗрд▓реНрдпреВ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдпрдерд╛рд╕рдВрднрд╡ рд╕рдорд╛рди рдФрд░ рд╕реНрдЯреИрдгреНрдбрд░реНрдб рд╣реИрд╢рдХреЛрдб рдХреЗ рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдкреВрд░реА рдХреЛрд╢рд┐рд╢ рдХреАред рд▓реЗрдХрд┐рди рдХрдИ рдХрд╛рд░рдг рд╣реИрдВ рдХрд┐ рдпреЗ рд╡рд┐рдзрд┐рдпрд╛рдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдореЗрдВ рдЦреЛ рдЬрд╛рддреА рд╣реИрдВ, рдЬреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИрдВ (рдпрд╛ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди)ред

1. рдкреИрдХреЗрдЬрд┐рдВрдЧ рд░реВрдкрд╛рдВрддрд░рдг рдХрд╛ рд╡рд┐рддрд░рдгред CLR рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ System.ValueType рдпрд╛ System.Enum рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рд╣рд░ рдХреЙрд▓ рдПрдХ рд░реИрдкрд┐рдВрдЧ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо (**) рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИред

(**) рдпрджрд┐ рд╡рд┐рдзрд┐ JIT рд╕рдВрдХрд▓рди рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЛрд░ рд╕реАрдПрд▓рдЖрд░ 2.1 рдореЗрдВ, рдЬреЗрдЖрдИрдЯреА рд╕рдВрдХрд▓рдХ Enum.HasFlag рд╡рд┐рдзрд┐ рдХреЛ Enum.HasFlag рд╣реИ рдФрд░ рдЙрдкрдпреБрдХреНрдд рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд▓рдкреЗрдЯрдирд╛ рд╢реБрд░реВ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

2. GetHashCode рд╡рд┐рдзрд┐ рдХреЗ рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рд░реЛрдзред рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдПрдХ рджреБрд╡рд┐рдзрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддреЗ рд╣реИрдВ: рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╡рд┐рддрд░рдг рдХреЛ рдЕрдЪреНрдЫрд╛ рдпрд╛ рддреЗрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЖрдк рджреЛрдиреЛрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди ValueType.GetHashCode рдкреНрд░рдХрд╛рд░ рдореЗрдВ, рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрддрд╛ рд╣реИред

рдПрдХ рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╣реИрд╢ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рдВрд░рдЪрдирд╛ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╣реИрд╢ рдХреЛрдб рдХреЛ рдЬреЛрдбрд╝рддреА рд╣реИред рд▓реЗрдХрд┐рди ValueType рд╡рд┐рдзрд┐ рдореЗрдВ рдлрд╝реАрд▓реНрдб рд╣реИрд╢ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИред рдЗрд╕реАрд▓рд┐рдП CLR рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдиреЗ рд╡рд┐рддрд░рдг рдХреЗ рд▓рд┐рдП рдЧрддрд┐ рдХрд╛ рддреНрдпрд╛рдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛, рдФрд░ GetHashCode рдХрд╛ рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдЧреИрд░-рд╢реВрдиреНрдп рдлрд╝реАрд▓реНрдб рдХреЗ рд╣реИрд╢ рдХреЛрдб рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (***) рдХреЗ рд╕рд╛рде " RegularGetValueTypeHashCode " рдХрд░рддрд╛ рд╣реИ (рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП RegularGetValueTypeHashCode рдкрд░ coreclr repo рдореЗрдВ RegularGetValueTypeHashCode рджреЗрдЦреЗрдВ)ред

(***) CoreCLR рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рднрд╡рд┐рд╖реНрдп рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдмрджрд▓ рд╕рдХрддреА рд╣реИред

 public readonly struct Location { public string Path { get; } public int Position { get; } public Location(string path, int position) => (Path, Position) = (path, position); } var hash1 = new Location(path: "", position: 42).GetHashCode(); var hash2 = new Location(path: "", position: 1).GetHashCode(); var hash3 = new Location(path: "1", position: 42).GetHashCode(); // hash1 and hash2 are the same and hash1 is different from hash3 

рдпрд╣ рдПрдХ рдЙрдЪрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реИ рдЬрдм рддрдХ рдХрд┐ рдХреБрдЫ рдЧрд▓рдд рди рд╣реЛ рдЬрд╛рдПред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рднрд╛рдЧреНрдп рд╕реЗ рдмрд╛рд╣рд░ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЗ рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╣рд▓реЗ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдореВрд▓реНрдп рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдореЗрдВ рд╕рдорд╛рди рд╣реИ, рддреЛ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рджреЗрдЧрд╛ред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рдпрд╛ рд╣реЛрдЧрд╛, рдпрджрд┐ рдЖрдк рдЗрди рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЛ рд╣реИрд╢ рд╕реЗрдЯ рдпрд╛ рд╣реИрд╢ рдЯреЗрдмрд▓ рдореЗрдВ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рджрд░реНрд╢рди рдШрдЯ рдЬрд╛рдПрдЧрд╛ред

3. рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЧрддрд┐ рдХрдо рд╣реИред рдмрд╣реБрдд рдХрдоред рдЕрдЧрд░ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдП рддреЛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдХреЛрдб рдХреЗ рд╕рдВрд╕рд╛рдзрди-рдЧрд╣рди рдЯреБрдХрдбрд╝реЗ рдкрд░ рдЪрд▓рд╛рддреЗ рд╣реИрдВ рддреЛ рдкрд░рд┐рдгрд╛рдо рднрдпрд╛рдирдХ рд╣реЛрдВрдЧреЗред

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдПрдХ рд╡рд┐рдлрд▓ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк (2) рдФрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдм-рдЖрдзрд╛рд░рд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ:

 public readonly struct Location1 { public string Path { get; } public int Position { get; } public Location1(string path, int position) => (Path, Position) = (path, position); } public readonly struct Location2 { // The order matters! // The default GetHashCode version will get a hashcode of the first field public int Position { get; } public string Path { get; } public Location2(string path, int position) => (Path, Position) = (path, position); } public readonly struct Location3 : IEquatable<Location3> { public string Path { get; } public int Position { get; } public Location3(string path, int position) => (Path, Position) = (path, position); public override int GetHashCode() => (Path, Position).GetHashCode(); public override bool Equals(object other) => other is Location3 l && Equals(l); public bool Equals(Location3 other) => Path == other.Path && Position == other.Position; } private HashSet<Location1> _locations1; private HashSet<Location2> _locations2; private HashSet<Location3> _locations3; [Params(1, 10, 1000)] public int NumberOfElements { get; set; } [GlobalSetup] public void Init() { _locations1 = new HashSet<Location1>(Enumerable.Range(1, NumberOfElements).Select(n => new Location1("", n))); _locations2 = new HashSet<Location2>(Enumerable.Range(1, NumberOfElements).Select(n => new Location2("", n))); _locations3 = new HashSet<Location3>(Enumerable.Range(1, NumberOfElements).Select(n => new Location3("", n))); _locations4 = new HashSet<Location4>(Enumerable.Range(1, NumberOfElements).Select(n => new Location4("", n))); } [Benchmark] public bool Path_Position_DefaultEquality() { var first = new Location1("", 0); return _locations1.Contains(first); } [Benchmark] public bool Position_Path_DefaultEquality() { var first = new Location2("", 0); return _locations2.Contains(first); } [Benchmark] public bool Path_Position_OverridenEquality() { var first = new Location3("", 0); return _locations3.Contains(first); } 


  Method | NumOfElements | Mean | Gen 0 | Allocated | -------------------------------- |------ |--------------:|--------:|----------:| Path_Position_DefaultEquality | 1 | 885.63 ns | 0.0286 | 92 B | Position_Path_DefaultEquality | 1 | 127.80 ns | 0.0050 | 16 B | Path_Position_OverridenEquality | 1 | 47.99 ns | - | 0 B | Path_Position_DefaultEquality | 10 | 6,214.02 ns | 0.2441 | 776 B | Position_Path_DefaultEquality | 10 | 130.04 ns | 0.0050 | 16 B | Path_Position_OverridenEquality | 10 | 47.67 ns | - | 0 B | Path_Position_DefaultEquality | 1000 | 589,014.52 ns | 23.4375 | 76025 B | Position_Path_DefaultEquality | 1000 | 133.74 ns | 0.0050 | 16 B | Path_Position_OverridenEquality | 1000 | 48.51 ns | - | 0 B | 

рдпрджрд┐ рдкрд╣рд▓реЗ рдлрд╝реАрд▓реНрдб рдХрд╛ рдорд╛рди рд╣рдореЗрд╢рд╛ рд╕рдорд╛рди рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди рдореВрд▓реНрдп рджреЗрддрд╛ рд╣реИ рдФрд░ рд╣реИрд╢ рд╕реЗрдЯ рдкреНрд░рднрд╛рд╡реА рд░реВрдк рд╕реЗ O (N) рд╕рдореНрдорд┐рд▓рд┐рдд рдФрд░ рдЦреЛрдЬ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред рд╕рдВрдЧреНрд░рд╣ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдЪрд╛рд▓рди рдХреА рд╕рдВрдЦреНрдпрд╛ рдУ (рдПрди ^ 2) рдмрди рдЬрд╛рддреА рд╣реИ (рдЬрд╣рд╛рдВ рдПрди рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рдЬрдЯрд┐рд▓рддрд╛ рдУ (рдПрди) рдХреЗ рд╕рд╛рде рдЖрд╡реЗрд╖рдг рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ)ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ 1000 рддрддреНрд╡реЛрдВ рдХреЗ рд╕реЗрдЯ рдореЗрдВ рдбрд╛рд▓рдиреЗ рд╕реЗ ValueType.Equals рд▓рдЧрднрдЧ 500,000 рдХреЙрд▓ ValueType.Equals ред рдпрд╣рд╛рдБ рдкрд░рд╛рд╡рд░реНрддрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╣реИрдВ!

рдЬреИрд╕рд╛ рдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрдк рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реИрдВ рдФрд░ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдкрд╣рд▓рд╛ рддрддреНрд╡ рдЕрджреНрд╡рд┐рддреАрдп рд╣реИ ( Position_Path_DefaultEquality рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ) рдкреНрд░рджрд░реНрд╢рди рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдмреЗрд╣рдж рдХрдо рд╣реЛрдЧреАред

рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдорд╕реНрдпрд╛


рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдм рдЖрдк рдЕрдиреБрдорд╛рди рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдХрд┐рд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд┐рдпрд╛ рд╣реИред рдХреБрдЫ рд╣рдлрд╝реНрддреЗ рдкрд╣рд▓реЗ рдореБрдЭреЗ рдПрдХ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рдорд┐рд▓рд╛: рдореИрдВ рдЬрд┐рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЙрд╕рдХрд╛ рд░рдирдЯрд╛рдЗрдо 10 рд╕реЗ 60 рд╕реЗрдХрдВрдб рддрдХ рдмрдврд╝ рдЧрдпрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд░рд┐рдкреЛрд░реНрдЯ рдмрд╣реБрдд рд╡рд┐рд╕реНрддреГрдд рдереА рдФрд░ рдЗрд╕рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдШрдЯрдирд╛рдУрдВ рдХрд╛ рдПрдХ рдЯреНрд░реЗрд╕ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╕рдорд╕реНрдпрд╛ рдХреА рдЬрдЧрд╣ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдЦреЛрдЬрд╛ рдЧрдпрд╛ рдерд╛ - ValueType.Equals рдиреЗ 50 рд╕реЗрдХрдВрдб рд▓реЛрдб рдХрд┐рдПред

рдХреЛрдб рдкрд░ рддреНрд╡рд░рд┐рдд рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреЗ рдмрд╛рдж, рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдХреНрдпрд╛ рдереА:

 private readonly HashSet<(ErrorLocation, int)> _locationsWithHitCount; readonly struct ErrorLocation { // Empty almost all the time public string OptionalDescription { get; } public string Path { get; } public int Position { get; } } 

рдореИрдВрдиреЗ рдПрдХ tuple рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд┐рд╕рдореЗрдВ Equals рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╕реНрдЯрдо рд╕рдВрд░рдЪрдирд╛ рдЯрд╛рдЗрдк рдХреА рдЧрдИ рдереАред рдФрд░ рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕рдореЗрдВ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рдкрд╣рд▓рд╛ рдХреНрд╖реЗрддреНрд░ рдерд╛, рдЬреЛ рд▓рдЧрднрдЧ рд╣рдореЗрд╢рд╛ String.equals рдмрд░рд╛рдмрд░реА String.equals ред рдЬрдм рддрдХ рд╕реЗрдЯ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрд╛рдлреА рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рд╣реБрдИ рддрдм рддрдХ рдЙрддреНрдкрд╛рджрдХрддрд╛ рдЕрдзрд┐рдХ рд░рд╣реАред рдХреБрдЫ рд╣реА рдорд┐рдирдЯреЛрдВ рдореЗрдВ, рд╣рдЬрд╛рд░реЛрдВ рддрддреНрд╡реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ред

рдХреНрдпрд╛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ ValueType.Equals/GetHashCode рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣рдореЗрд╢рд╛ рдзреАрдореА рдЧрддрд┐ рд╕реЗ рдЪрд▓ рд░рд╣рд╛ рд╣реИ?


ValueType.Equals рдФрд░ ValueType.GetHashCode рджреЛрдиреЛрдВ рдореЗрдВ рд╡рд┐рд╢реЗрд╖ рдЕрдиреБрдХреВрд▓рди рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВред рдпрджрд┐ рдкреНрд░рдХрд╛рд░ рдореЗрдВ "рдкреЙрдЗрдВрдЯрд░реНрд╕" рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕реЗ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдкреИрдХ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдореИрдВ рдПрдХ рдорд┐рдирдЯ рдореЗрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛рдКрдВрдЧрд╛), рддреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: GetHashCode рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдмреНрд▓реЙрдХ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, 4 рдмрд╛рдЗрдЯреНрд╕ рдХреЗ XOR рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, Equals рд╡рд┐рдзрд┐ memcmp рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреЛ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рддреБрд▓рдирд╛ memcmp ред

 // Optimized ValueType.GetHashCode implementation static INT32 FastGetValueTypeHashCodeHelper(MethodTable *mt, void *pObjRef) { INT32 hashCode = 0; INT32 *pObj = (INT32*)pObjRef; // this is a struct with no refs and no "strange" offsets, just go through the obj and xor the bits INT32 size = mt->GetNumInstanceFieldBytes(); for (INT32 i = 0; i < (INT32)(size / sizeof(INT32)); i++) hashCode ^= *pObj++; return hashCode; } // Optimized ValueType.Equals implementation FCIMPL2(FC_BOOL_RET, ValueTypeHelper::FastEqualsCheck, Object* obj1, Object* obj2) { TypeHandle pTh = obj1->GetTypeHandle(); FC_RETURN_BOOL(memcmp(obj1->GetData(), obj2->GetData(), pTh.GetSize()) == 0); } 

рдЪреЗрдХ рдЦреБрдж ValueTypeHelper::CanCompareBits рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ValueTypeHelper::CanCompareBits , рдЗрд╕реЗ ValueType.Equals рдХреЗ ValueType.Equals рдФрд░ ValueType.Equals рдХреА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕реЗ рджреЛрдиреЛрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред

рд▓реЗрдХрд┐рди рдЕрдиреБрдХреВрд▓рди рдПрдХ рдмрд╣реБрдд рд╣реА рдХрдкрдЯреА рдмрд╛рдд рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдпрд╣ рд╕рдордЭрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХрдм рдЪрд╛рд▓реВ рдХрд┐рдпрд╛ рдЬрд╛рдП; рдХреЛрдб рдореЗрдВ рдорд╛рдореВрд▓реА рдмрджрд▓рд╛рд╡ рднреА рдЗрд╕реЗ рдЪрд╛рд▓реВ рдФрд░ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 public struct Case1 { // Optimization is "on", because the struct is properly "packed" public int X { get; } public byte Y { get; } } public struct Case2 { // Optimization is "off", because struct has a padding between byte and int public byte Y { get; } public int X { get; } } 

рд╕реНрдореГрддрд┐ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдореЗрд░рд╛ рдмреНрд▓реЙрдЧ, "рдПрдХ рдкреНрд░рдмрдВрдзрд┐рдд рд╡рд╕реНрддреБ рдХрд╛ рдЖрдВрддрд░рд┐рдХ рддрддреНрд╡, рднрд╛рдЧ 4. рдлрд╝реАрд▓реНрдб рд╕рдВрд░рдЪрдирд╛" рджреЗрдЦреЗрдВ ред

рджреВрд╕рд░реЗ, рд╕реНрдореГрддрд┐ рдХреА рддреБрд▓рдирд╛ рдЬрд░реВрд░реА рдирд╣реАрдВ рдХрд┐ рдЖрдкрдХреЛ рд╕рд╣реА рдкрд░рд┐рдгрд╛рдо рджреЗред рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

 public struct MyDouble { public double Value { get; } public MyDouble(double value) => Value = value; } double d1 = -0.0; double d2 = +0.0; // True bool b1 = d1.Equals(d2); // False! bool b2 = new MyDouble(d1).Equals(new MyDouble(d2)); 

+0,0 рдФрд░ +0,0 рд╕рдорд╛рди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдмрд╛рдЗрдирд░реА рдЕрднреНрдпрд╛рд╡реЗрджрди рд╣реИрдВред рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ Double.Equals рд╕рддреНрдп рд╣реИ рдФрд░ Double.Equals рдЧрд▓рдд рд╣реИред рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЕрдВрддрд░ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдЖрдк рдЗрд╕ рдЕрдВрддрд░ рдХреЗ рдХрд╛рд░рдг рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдореЗрдВ рдХрд┐рддрдиреЗ рдШрдВрдЯреЗ рдмрд┐рддрд╛рдПрдВрдЧреЗред

рдЗрд╕реА рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛ рд╕реЗ рдХреИрд╕реЗ рдмрдЪреЗрдВ?


рдХреНрдпрд╛ рдЖрдк рдореБрдЭрд╕реЗ рдкреВрдЫ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдХреИрд╕реЗ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ? Equals рдкреНрд░рдХрд╛рд░ рдФрд░ Equals рдкреНрд░рдХрд╛рд░ рдХреЗ GetHashCode рддрд░реАрдХреЛрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХрд╛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рддрд░реАрдХрд╛ рд╣реИ FxCop CA1815 рдирд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рд▓реЗрдХрд┐рди рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ: рдпрд╣ рдмрд╣реБрдд рд╕рдЦреНрдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИред

рдПрдХ рдРрд╕рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рджрд░реНрд╢рди рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рд╕реИрдХрдбрд╝реЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрд░рдЪрдирд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд░реВрдк рд╕реЗ рд╣реИрд╢ рд╕реЗрдЯ рдпрд╛ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдирд┐рдпрдо рдХреЛ рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдЕрдкреНрд░рд┐рдп рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрд╛рд░рдг рд╣реЛрдЧрд╛ рдпрджрд┐ рд╕рдВрд░рдЪрдирд╛ рдкреНрд░рдХрд╛рд░ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдПрдХ рдЕрдзрд┐рдХ рд╕рд╣реА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдЪреЗрддрд╛рд╡рдиреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИ рдпрджрд┐ "рдЕрдиреБрдкрдпреБрдХреНрдд" рдкреНрд░рдХрд╛рд░ рдХреЗ рддрддреНрд╡реЛрдВ рдХреЗ рд╕рдорд╛рди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрд░рдЪрдирд╛ (рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдпрд╛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд) рдПрдХ рд╣реИрд╢ рд╕реЗрдЯ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рдмреЗрд╢рдХ рдореИрдВ ErrorProne.NET рдФрд░ рдирд┐рдпрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдБ рдЬреИрд╕реЗ рд╣реА рдореИрдВ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛



ErrorProne.NET рд╕рдВрд╕реНрдХрд░рдг рд╕рд╣реА рдирд╣реАрдВ рд╣реИ рдФрд░ рд╕рд╣реА рдХреЛрдб рдХреЛ "рджреЛрд╖" рджреЗрдЧрд╛ рдпрджрд┐ рдХрд╕реНрдЯрдо рд╕рдорд╛рдирддрд╛ рд░рд┐рдЬрд╝реЙрд▓реНрд╡рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:



рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЕрднреА рднреА рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдЙрддреНрдкрд╛рджрди рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕рдорд╛рди рддрддреНрд╡реЛрдВ рд╡рд╛рд▓реЗ рдХрд┐рд╕реА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЪреЗрддрд╛рд╡рдиреА рдХреЗ рд▓рд╛рдпрдХ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдирд┐рдпрдо рдХреА рдЬрд╛рдБрдЪ рдХреА, рддреЛ рдореИрдВрдиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ System.Collections.Generic.KeyValuePair <TKey, TValue> mscorlib рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рд╕рдВрд░рдЪрдирд╛ Equals рдФрд░ GetHashCode рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдпрд╣ рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреЛрдИ рднреА HashSet <KeyValuePair<string, int>> рдЬреИрд╕реЗ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рдореЗрд░рд╛ рдорд╛рдирдирд╛ тАЛтАЛрд╣реИ рдХрд┐ BCL рдирд┐рдпрдо рдХреЛ рддреЛрдбрд╝ рднреА рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдмрд╣реБрдд рджреЗрд░ рд╣реЛ рдЬрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕ рдХреА рдЦреЛрдЬ рдХрд░рдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реИред

рдирд┐рд╖реНрдХрд░реНрд╖


  • рд╕рдВрд░рдЪрдирд╛рддреНрдордХ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдорд╛рдирддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдЖрдкрдХреЗ рдЖрд╡реЗрджрди рдХреЗ рдЧрдВрднреАрд░ рдкрд░рд┐рдгрд╛рдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ, рдПрдХ рд╕реИрджреНрдзрд╛рдВрддрд┐рдХ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИред
  • рдореВрд▓реНрдп рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдорд╛рдирддрд╛ рддрддреНрд╡ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред
  • GetHashCode рдХреЗ рдорд╛рдирдХ рд╕рдВрд╕реНрдХрд░рдг рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╡рд┐рддрд░рдг рдмрд╣реБрдд рдЦрд░рд╛рдм рд╣реЛрдЧрд╛ рдпрджрд┐ рдХрдИ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рдкрд╣рд▓реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рд╕рдорд╛рди рдореВрд▓реНрдп рд╣реЛред
  • рдорд╛рдирдХ Equals рдФрд░ GetHashCode рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЙрди рдкрд░ рднрд░реЛрд╕рд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдПрдХ рдЫреЛрдЯрд╛ рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди рднреА рдЙрдиреНрд╣реЗрдВ рдмрдВрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред
  • рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд░рдЪрдирд╛ рдкреНрд░рдХрд╛рд░ рд╕рдорд╛рдирддрд╛ рддрддреНрд╡реЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рддреА рд╣реИ, FxCop рдирд┐рдпрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдмреЗрд╣рддрд░ рд╣реИ рдЕрдЧрд░ "рдЕрдиреБрдЪрд┐рдд" рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╣реИрд╢ рд╕реЗрдЯ рдпрд╛ рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдВрд╕рд╛рдзрди


Source: https://habr.com/ru/post/hi418515/


All Articles