There are a couple of ways you can do this. By default Equals() and == check for reference equality, meaning:
Person a = new Person();
Person b = a:
a.Equals(b); //true
a == b; //true
And therefore, the objects are not compared for value equality, meaning:
Person a = new Person { id = 1, name = "person1" };
Person b = new Person { id = 1, name = "person1" };
a.Equals(b); //false
a == b; //false
To compare objects for their values you can override the Equals() and GetHashcode() methods, like this:
public override bool Equals(System.Object obj)
{
    if (obj == null)
        return false;
    Person p = obj as Person;
    if ((System.Object)p == null)
        return false;
    return (id == p.id) && (name == p.name);
}
public bool Equals(Person p)
{
    if ((object)p == null)
        return false;
    return (id == p.id) && (name == p.name);
}
public override int GetHashCode()
{
    return id.GetHashCode() ^ name.GetHashCode();
}
Now you will see other results when comparing:
Person a = new Person { id = 1, name = "person1" };
Person b = new Person { id = 1, name = "person1" };
Person c = a;
a == b; //false
a == c; //true
a.Equals(b); //true
a.Equals(c); //true
The == operator is not overridden and therefore still does reference comparison. This can be solved by overloading it as well as the != operator:
public static bool operator ==(Person a, Person b)
{
    if (System.Object.ReferenceEquals(a, b))
        return true;
    if ((object)a == null || (object)b == null)
        return false;
    return a.id == b.id && a.name == b.name;
}
public static bool operator !=(Person a, Person b)
{
    return !(a == b);
}
Now running the checks results in following:
Person a = new Person { id = 1, name = "person1" };
Person b = new Person { id = 1, name = "person1" };
Person c = a;
a == b; //true
a == c; //true
a.Equals(b); //true
a.Equals(c); //true
More reading: