我写了一个验证属性来使条件必需成为可能。
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 :(得分:3)
valToCompare
和_value
被静态输入为object
。这意味着,在==
运算符期间,只检查引用相等性,就像检查任何普通对象一样。
.Net不知道(也不检查)这些对象是否有任何特殊之处。即使你覆盖operator==
,.Net也不会调用它,因为变量的类型只是" object"。它仍将使用最基本的运算符==来检查引用相等性(对于结构,值相等......)。
另一方面,当你调用Equals
方法,即virtual
btw时,一切正常,因为你的等式检查已经执行了。事实上,你明确地命令它们被执行。就像任何来自基类的重写虚拟方法一样。
btw2。如果null
中valToCompare
,则应使用不会抛出NullReferenceException的object.Equals(valToCompare, _value)
。