条件为真时评估为假。

huangapple go评论77阅读模式
英文:

True condition evaluates to false

问题

我正在编写一个基本的模型验证器,该验证器使用自定义的“Required”属性和反射。当一个模型传递给验证器方法时,会检查所有属性是否具有此必需属性。复杂类型也会进行递归验证。当发现带有此属性的属性时,如果它是可空类型,它将将值与null进行比较,否则将与默认值进行比较。

当将非可空类型与默认值进行比较时,我遇到了问题。以下条件对于int类型评估为false,但应该为true:

if (prop.GetValue(testObject) == default)
{
    Console.WriteLine($"{VALIDATION_FAILED_MESSAGE}: {baseObjectName}{testObject.GetType().Name}.{prop.Name} is null.");
    isNullorDefault = true;
}

我在调试器中看到,被比较的值毫无疑问是默认值 ->
default(int) == 0,但它评估为false。为什么?

条件为真时评估为假。

英文:

I am writing a basic model validator that uses reflection with a custom "Required" attribute. When a model is passed into the validator method, all properties are checked for this required attribute. Complex types are recursively validated as well. When a property is found with this attribute, it will either compare the value to null if it is a nullable type, else it will compare to default.

I'm having issues when comparing non-nullable type to default. The following condition is evaluating to false for type int, but it should be true:

if (prop.GetValue(testObject) == default)
{
    Console.WriteLine($"{VALIDATION_FAILED_MESSAGE}: {baseObjectName}{testObject.GetType().Name}.{prop.Name} is null.");
    isNullorDefault = true;
}

I see in the debugger that the value being compared is without a doubt the default value ->
default(int) == 0, but it is evaluating to false. Why?

条件为真时评估为假。

答案1

得分: 7

以下是翻译的内容:

好的,这里有一些事实:

  • GetValue 返回一个 object,它是一个引用类型。
  • 对象上的 == 进行引用比较(所以如果两者是相同的对象则为真)。
  • 值类型在转换为 object 时总是装箱到一个新的对象中。
  • 没有类型的 default 根据上下文被简单地推断为 object,所以是 null

因此,这种比较永远不会评估为真:装箱的值类型永远不会是 null,即使你执行 GetValue(x) == (object)0,它仍然为假,因为这个 0 会装箱到一个不同的对象中,因此不同的引用会不同地进行比较。

所以这就是为什么会发生这种情况的答案。至于你实际尝试做的事情的解决方案,请参考这个问题

英文:

Well, here are a few facts:

  • GetValue returns an object, which is a reference type
  • == on objects does a reference comparison (so true if both are the same object).
  • Value types are always boxed to a new object when cast to object.
  • default without a type is simply inferred based on context, and here it's object, so null.

Therefore, this comparison can never evaluate to true: a boxed value type is never null, and even if you did GetValue(x) == (object)0, it would still be false because that 0 would get boxed to a different object, and as such, different references compare differently.

So that's your answer as for why this is happening. For a solution to the actual thing you're trying to do, see this question.

huangapple
  • 本文由 发表于 2023年6月15日 12:52:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76479220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定