簡體   English   中英

枚舉失敗==通過反射檢索值時

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM