# equals
**Repository Path**: mirrors_Fody/equals
## Basic Information
- **Project Name**: equals
- **Description**: Generate Equals, GetHashCode and operators methods from properties.
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2023-02-24
- **Last Updated**: 2026-02-15
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#
Equals
[](https://www.nuget.org/packages/Equals.Fody/)
Generate Equals, GetHashCode and operator methods from properties for classes decorated with an `[Equals]` Attribute
**See [Milestones](../../milestones?state=closed) for release notes.**
### This is an add-in for [Fody](https://github.com/Fody/Home/)
**It is expected that all developers using Fody either [become a Patron on OpenCollective](https://opencollective.com/fody/contribute/patron-3059), or have a [Tidelift Subscription](https://tidelift.com/subscription/pkg/nuget-fody?utm_source=nuget-fody&utm_medium=referral&utm_campaign=enterprise). [See Licensing/Patron FAQ](https://github.com/Fody/Home/blob/master/pages/licensing-patron-faq.md) for more information.**
## Usage
See also [Fody usage](https://github.com/Fody/Home/blob/master/pages/usage.md).
### NuGet installation
Install the [Equals.Fody NuGet package](https://nuget.org/packages/Equals.Fody/) and update the [Fody NuGet package](https://nuget.org/packages/Fody/):
```powershell
PM> Install-Package Fody
PM> Install-Package Equals.Fody
```
The `Install-Package Fody` is required since NuGet always defaults to the oldest, and most buggy, version of any dependency.
### Add to FodyWeavers.xml
Add `` to [FodyWeavers.xml](https://github.com/Fody/Home/blob/master/pages/usage.md#add-fodyweaversxml)
```xml
```
## Your Code
```csharp
[Equals]
public class Point
{
public int X { get; set; }
public int Y { get; set; }
[IgnoreDuringEquals]
public int Z { get; set; }
[CustomEqualsInternal]
bool CustomLogic(Point other)
{
return Z == other.Z || Z == 0 || other.Z == 0;
}
public static bool operator ==(Point left, Point right) => Operator.Weave(left, right);
public static bool operator !=(Point left, Point right) => Operator.Weave(left, right);
}
[Equals]
public class CustomGetHashCode
{
public int X { get; set; }
[IgnoreDuringEquals]
public int Z { get; set; }
[CustomGetHashCode]
int CustomGetHashCodeMethod()
{
return 42;
}
public static bool operator ==(CustomGetHashCode left, CustomGetHashCode right) => Operator.Weave(left, right);
public static bool operator !=(CustomGetHashCode left, CustomGetHashCode right) => Operator.Weave(left, right);
}
```
Note:
- unless you specify `[Equals(DoNotAddEqualityOperators = true)]`, you must always add the `==` and `!=` method stubs with the `Operator.Weave()` implementation (if you want to know why, see [#10](https://github.com/Fody/Equals/issues/10)).
- adding the `==` and `!=` operators will result in compiler warnings CS0660 and CS0661, which tell you to implement custom `Equals` and `GetHashCode` implementations. Equals.Fody is doing this for you, but after the compiler runs. To suppress the false-positives you can either do so
- per project, by adding `CS0660;CS0661` to the project file
- per source file, by adding `#pragma warning disable CS0660, CS0661`.
- implementing a custom hash code method (marked by `[CustomGetHashCode]`) is optional.
## What gets compiled
```csharp
public class Point : IEquatable
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
bool CustomLogic(Point other)
{
return Z == other.Z || Z == 0 || other.Z == 0;
}
public static bool operator ==(Point left, Point right)
{
return object.Equals((object)left, (object)right);
}
public static bool operator !=(Point left, Point right)
{
return !object.Equals((object)left, (object)right);
}
static bool EqualsInternal(Point left, Point right)
{
return left.X == right.X && left.Y == right.Y && leftt.CustomLogic(right);
}
public virtual bool Equals(Point right)
{
return !object.ReferenceEquals((object)null, (object)right) && (object.ReferenceEquals((object)this, (object)right) || Point.EqualsInternal(this, right));
}
public override bool Equals(object right)
{
return !object.ReferenceEquals((object)null, right) && (object.ReferenceEquals((object)this, right) || this.GetType() == right.GetType() && Point.EqualsInternal(this, (Point)right));
}
public override int GetHashCode()
{
return unchecked(this.X.GetHashCode() * 397 ^ this.Y.GetHashCode());
}
}
public class CustomGetHashCode : IEquatable
{
public int X { get; set; }
public int Z { get; set; }
int CustomGetHashCodeMethod()
{
return 42;
}
static bool EqualsInternal(CustomGetHashCode left, CustomGetHashCode right)
{
return left.X == right.X;
}
public override bool Equals(CustomGetHashCode other)
{
return !object.ReferenceEquals(null, other) && (object.ReferenceEquals(this, other) || CustomGetHashCode.EqualsInternal(this, other));
}
public override bool Equals(object obj)
{
return !object.ReferenceEquals(null, obj) && (object.ReferenceEquals(this, obj) || (base.GetType() == obj.GetType() && CustomGetHashCode.EqualsInternal(this, (CustomGetHashCode)obj)));
}
public override int GetHashCode()
{
return (this.X.GetHashCode() * 397) ^ this.CustomGetHashCodeMethod();
}
public static bool operator ==(CustomGetHashCode left, CustomGetHashCode right)
{
return object.Equals(left, right);
}
public static bool operator !=(CustomGetHashCode left, CustomGetHashCode right)
{
return !object.Equals(left, right);
}
}
```
## Configurability
Through properties on the `[Equals]` attribute the following options can be set:
- `DoNotAddEqualityOperators` => do not weave `==` and `!=` operators
- `DoNotAddGetHashCode` => do not override the `int GetHashCode()` methods
- `DoNotAddEquals` => do not override the `bool Equals(object other)` method, do not add and implement `IEquatable`
- `IgnoreBaseClassProperties` => equality and hash code do not consider properties of base classes.
- `TypeCheck` can be used to affect the equality logic.
- `ExactlyTheSameTypeAsThis` (*default*): only equal, when the other object is of the same type as `this`. Imagine we have a class `Foo` with `[Equals]` and we have a sub-`class Bar : Foo`:
- `Foo` may equal `Foo`
- `Bar` may equal `Bar`
- but `Foo` may never equal `Bar`
- `ExactlyOfType`: only equal, when the other object is of the same as the method is added to. Consider a class `Foo` with `[Equals(TypeCheck = ExactlyOfType)]` and a sub-`class Bar : Foo`:
- `Foo` may equal `Foo`
- `Bar` may never equal `Bar`
- `Foo` may never equal `Bar`
- `EqualsOrSubtype`: equal, when the other object is of same type as the method is added to, or is of a sub type.
## Icon
Icon courtesy of [The Noun Project](https://thenounproject.com)