Implement IEquatable on structs.

Any struct which overrides object.Equals(object obj) should implement IEquatable<T> to gain a more efficient Equals(T other) overload. This overload will be used by hashing collections like Dictionary which enables them to check equality without boxing the struct.
This commit is contained in:
RoosterDragon
2019-09-14 00:33:27 +01:00
committed by teinarss
parent 4a609bbee8
commit 6c9fbd40dc
6 changed files with 33 additions and 17 deletions

View File

@@ -9,9 +9,11 @@
*/ */
#endregion #endregion
using System;
namespace OpenRA namespace OpenRA
{ {
public struct Hotkey public struct Hotkey : IEquatable<Hotkey>
{ {
public static Hotkey Invalid = new Hotkey(Keycode.UNKNOWN, Modifiers.None); public static Hotkey Invalid = new Hotkey(Keycode.UNKNOWN, Modifiers.None);
public bool IsValid() public bool IsValid()
@@ -74,6 +76,11 @@ namespace OpenRA
public override int GetHashCode() { return Key.GetHashCode() ^ Modifiers.GetHashCode(); } public override int GetHashCode() { return Key.GetHashCode() ^ Modifiers.GetHashCode(); }
public bool Equals(Hotkey other)
{
return other == this;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
var o = obj as Hotkey?; var o = obj as Hotkey?;

View File

@@ -15,7 +15,7 @@ using OpenRA.Scripting;
namespace OpenRA.Primitives namespace OpenRA.Primitives
{ {
public struct Color : IScriptBindable public struct Color : IEquatable<Color>, IScriptBindable
{ {
readonly long argb; readonly long argb;
@@ -200,6 +200,11 @@ namespace OpenRA.Primitives
public byte G { get { return (byte)(argb >> 8); } } public byte G { get { return (byte)(argb >> 8); } }
public byte B { get { return (byte)argb; } } public byte B { get { return (byte)argb; } }
public bool Equals(Color other)
{
return this == other;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (!(obj is Color)) if (!(obj is Color))

View File

@@ -66,17 +66,5 @@ namespace OpenRA.Primitives
public static class Pair public static class Pair
{ {
public static Pair<T, U> New<T, U>(T t, U u) { return new Pair<T, U>(t, u); } public static Pair<T, U> New<T, U>(T t, U u) { return new Pair<T, U>(t, u); }
static Pair()
{
Pair<char, Color>.Ucomparer = new ColorEqualityComparer();
}
// avoid the default crappy one
class ColorEqualityComparer : IEqualityComparer<Color>
{
public bool Equals(Color x, Color y) { return x.ToArgb() == y.ToArgb(); }
public int GetHashCode(Color obj) { return obj.GetHashCode(); }
}
} }
} }

View File

@@ -13,7 +13,7 @@ using System;
namespace OpenRA.Primitives namespace OpenRA.Primitives
{ {
public struct Rectangle public struct Rectangle : IEquatable<Rectangle>
{ {
// TODO: Make these readonly: this will require a lot of changes to the UI logic // TODO: Make these readonly: this will require a lot of changes to the UI logic
public int X; public int X;
@@ -76,6 +76,11 @@ namespace OpenRA.Primitives
return Contains(pt.X, pt.Y); return Contains(pt.X, pt.Y);
} }
public bool Equals(Rectangle other)
{
return this == other;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (!(obj is Rectangle)) if (!(obj is Rectangle))

View File

@@ -13,7 +13,7 @@ using System;
namespace OpenRA.Primitives namespace OpenRA.Primitives
{ {
public struct Size public struct Size : IEquatable<Size>
{ {
public readonly int Width; public readonly int Width;
public readonly int Height; public readonly int Height;
@@ -46,6 +46,11 @@ namespace OpenRA.Primitives
public bool IsEmpty { get { return Width == 0 && Height == 0; } } public bool IsEmpty { get { return Width == 0 && Height == 0; } }
public bool Equals(Size other)
{
return this == other;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
if (!(obj is Size)) if (!(obj is Size))

View File

@@ -9,6 +9,7 @@
*/ */
#endregion #endregion
using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -16,7 +17,7 @@ namespace OpenRA
{ {
[SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:ElementMustBeginWithUpperCaseLetter", Justification = "Mimic a built-in type alias.")] [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:ElementMustBeginWithUpperCaseLetter", Justification = "Mimic a built-in type alias.")]
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct float3 public struct float3 : IEquatable<float3>
{ {
public readonly float X, Y, Z; public readonly float X, Y, Z;
public float2 XY { get { return new float2(X, Y); } } public float2 XY { get { return new float2(X, Y); } }
@@ -47,6 +48,11 @@ namespace OpenRA
public static bool operator !=(float3 me, float3 other) { return !(me == other); } public static bool operator !=(float3 me, float3 other) { return !(me == other); }
public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); } public override int GetHashCode() { return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); }
public bool Equals(float3 other)
{
return other == this;
}
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
var o = obj as float3?; var o = obj as float3?;