[英]Enum failing == when value retrieved via reflection
我正在嘗試為MVC 6實現自定義jQuery Unobtrusive Validation屬性。下面是該屬性的IsValid()
實現,該屬性查看類中的相鄰屬性並將其與編譯時常量進行比較。
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult result = ValidationResult.Success;
// Simplest case, there is something in this field
if (!string.IsNullOrEmpty(value?.ToString()))
return result;
// Check relative field
try
{
// Grab the property referenced via reflection
var relativeProperty = validationContext.ObjectType.GetProperty(this._relativePropertyName);
// Compare the runtime value of that property to the Attribute initialized value
if (relativeProperty.GetValue(validationContext.ObjectInstance) == this._relativeValue)
{
// Fail if those 2 values are equal
result = new ValidationResult(this.ErrorMessageString);
}
}
catch (Exception)
{
result = new ValidationResult(this.ErrorMessageString);
}
return result;
}
在大多數情況下,這完全符合預期。 我唯一遇到的問題是當引用的屬性及其值是Enum的派生類時(例如,讓我們假設枚舉為Result
)。 在一個類中,實現此屬性的外觀如下:
public class TestObject
{
public Result TestResult { get; set; }
[IsEqual(nameof(TestResult), Result.Pass)]
public string PassComment { get; set; }
}
當調試器到達if(relativeProperty.GetValue(validationContext.ObjectInstance) == this._relativeValue)
,即使relativeProperty.GetValue(validationContext.ObjectInstance)
解析為Result.Pass
,它也會失敗。 使用立即窗口, relativeProperty.GetValue(validationContext.ObjectInstance)
= Result.Pass
以及this._relativeValue
= Result.Pass
小注釋,在兩個值上調用.GetType()
也相等。
我假設這與拳擊有關,但無法查明。 提前致謝。
不要使用==
來評估非強類型輸入的相等性。 考慮以下:
void Main()
{
Console.WriteLine(((object)Result.Pass) == (object)Result.Pass);
// False
Console.WriteLine(((object)Result.Pass).Equals((object)Result.Pass));
// True
Console.WriteLine(object.Equals((object)Result.Pass,(object)Result.Pass));
// True
}
public enum Result{
Pass, Fail
}
在C#中,可以重寫==
運算符以使比較某些類型的對象時的語法更容易,如果您嘗試==
兩個不兼容的類型,則具有提供編譯時錯誤的優點。 有些人認為它看起來更好。
但是,當值向下轉換到object
s時, object == object
操作符將執行Object.ReferenceEquals()
檢查。 由於枚舉是值類型,因此必須將它們“裝箱”到新對象中才能轉換為objects
,並且這些新對象將存在於不同的內存位置。 因此, ReferenceEquals()
將為false。
而是使用object.Equals()
方法,該方法傳遞給各個類的.Equals()
覆蓋。 在這種情況下,Enum類型對.Equals()
的覆蓋將檢查該值是否可以轉換為Result
,以及結果值是否與this
值相同。
與value1.Equals(value2)
object.Equals(value1, value2)
, value1.Equals(value2)
object.Equals(value1, value2)
的優勢在於object.Equals(value1, value2)
如果value1
為null,則不會獲得null異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.