Q:

C# ValidationResult value equality assertion fails with Assert.AreEqual

I have a simple ValidationRule implementation :
public class IntegerRangeRule : ValidationRule
{
    public Int32 Max { get; set; }
    public Int32 Min { get; set; }

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        int integer;

        if(string.IsNullOrEmpty((string)value))
        {
            return new ValidationResult(false, "Field cannot be empty");
        }

        if (Int32.TryParse((string) value, out integer))
        {
            if((integer < Min) || (integer > Max))
                return new ValidationResult(false, string.Format("Enter a value between {0} and {1}.", Min, Max));
        }
        else
        {
            return new ValidationResult(false, "Illegal characters: " + (string)value);
        }

        return ValidationResult.ValidResult;
    }
}

I wrote the following unit test for the Validation method:
[TestMethod()]
public void ValidateTest_InputTooSmall()
{
    //Setup
    var target = new IntegerRangeRule()
    {
        Max = 100,
        Min = 1
    };
    var expected = new ValidationResult(false, "Enter a value between 1 and 100.");

    //Exercise
    var actual = target.Validate("0", null);

    //Verify
    Assert.AreEqual(expected.ErrorContent, actual.ErrorContent);
    Assert.AreEqual(expected.IsValid, actual.IsValid);
    Assert.AreEqual(expected.GetHashCode(), actual.GetHashCode());
    Assert.AreEqual(expected, actual);
}

Here is the catch. 
The first three assertions all pass. But the last one fails. 
If I replace the 
...
    if (Int32.TryParse((string) value, out integer))
    {
        if((integer < Min) || (integer > Max))
            return new ValidationResult(false, string.Format("Enter a value between {0} and {1}.", Min, Max));
    }
...

with a constant string.
...
    if (Int32.TryParse((string) value, out integer))
    {
        if((integer < Min) || (integer > Max))
            return new ValidationResult(false, "Enter a value between 1 and 100.");
    }
...

The last assertion will pass. 
I dont understand what is causing the problem here. Thank you.

A:

ValidationResult contains this in Equals:
return (IsValid == vr.IsValid) && (ErrorContent == vr.ErrorContent);

Since ErrorContent is an object, this is a reference comparison, not a value comparison. In your case you are generating a new string using String.Format and comparing that reference to a literal, so the result is always false. When you change it to the same literal string it passes because literals are interned by the CLR.
Meanwhile your testing framework is probably calling Object.Equals(object, object) inside its Assert.AreEqual method, which invokes String's overridden Equals method. This does a value comparison.

