2014-09-22 81 views
1

我寫了一個驗證屬性來使條件Required是可能的。爲什麼兩個相等比較的結果不同,取決於操作員?

public class RequiredIfEqualsAttribute : RequiredAttribute 
{ 
    private readonly string _otherProperty; 
    private readonly object _value; 

    public RequiredIfEqualsAttribute(string otherProperty, object value) 
     : base() 
    { 
     this._otherProperty = otherProperty; 
     this._value = value; 
    } 

    protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var valToCompare = validationContext.ObjectInstance.GetType().GetProperty(_otherProperty).GetValue(validationContext.ObjectInstance, null); 
     if (valToCompare == _value) 
     { 
      return base.IsValid(value, validationContext); 
     } 
     return null; 
    } 
} 

這是很容易使用:

[EnumDataType(typeof(SomeEnum))] 
[Required] 
public SomeEnum SomeType { get; set; } 

[RequiredIfEquals("SomeType", SomeEnum.A)] 
public string A { get; set; } 

[RequiredIfEquals("SomeType", SomeEnum.B)] 
public string B { get; set; } 

我注意到一個奇怪的現象,雖然。該行:

if (valToCompare == _value) 

實際上將評估爲false,即使valToCompare_value都代表SomeEnum.A

是否因爲_value是隻讀的?當我用下面一切正常:

if (valToCompare.Equals(_value)) 

在這種情況下,如果valToCompare_value都表示SomeEnum.A,該聲明將評估爲true,因爲它應該。

誰能賜教我?

+0

在C#中,'=='和'Equals()'是不一樣的,每個運算符都可以被重寫爲具有不同的邏輯。然而,通常'=='表示引用相等,而Equals()表示值相等。 – 2014-09-22 09:38:04

回答

3

valToCompare_value靜態類型爲object。這意味着,在==運算符中,只有引用相等纔會被檢查,就像任何普通對象一樣。

.Net不知道(也不檢查)這些對象是否以任何方式特殊。即使你忽略了operator==,.Net也不會調用它,因爲變量的類型只是「對象」。它仍然會使用最基本的運算符==來檢查引用是否相等(對於結構,值相等..)。

另一方面,當您撥打Equals方法,這是virtual順便說一句,一切正常,因爲您的平等檢查被執行。事實上,你明確命令他們執行。就像任何從基類重寫的虛擬方法一樣。

btw2。在nullvalToCompare的情況下,您應該使用object.Equals(valToCompare, _value),它不會拋出NullReferenceException。

+0

優秀的解釋,謝謝。我會盡快接受你的回答。 – Korijn 2014-09-22 09:38:24

相關問題