setter 中的价值评估甚至没有被检查

发布于 2024-09-30 19:08:06 字数 1160 浏览 2 评论 0原文

我在复合控件中有一个属性,它在实际设置相关私有字段并执行其他一些操作之前检查值是否已更改。

然而,它似乎从未评估过这一声明。

以下是该属性的代码:

public T SearchCriteria
        {
            get
            {
                return mySearchCriteria;
            }
            set
            {
                if (value != mySearchCriteria)
                {
                    mySearchCriteria = value;
                    EnsureChildControls();
                    SearchGridParser parser = SearchGridParserFactory.GetParser(this.Type);
                    parser.SetSearchPanelControls<T>(this.mySearchCriteria, ref mySearchParametersPanel);
                    GridView.PageIndex = 0;
                }
            }
        }

我已经单步执行了代码,每次到达“value != mySearchCriteria”时,它都会计算为 false 并跳过 if 语句内的代码。事实上,即使我将其更改为“value == mySearchCriteria”,它也会这样做。如果无论它如何评估,都完全跳过它!

什么啊嘿?

我尝试更改检查中参数的顺序,并使用 object.Equals() 但这些更改都没有产生任何区别。

我已经重写了 Equals、!=、== 和 GetHashCode。

代码中的其他地方对这些对象类型使用“==”和“!=”没有问题,所以我知道我的重写工作正常。

问题是,这甚至从未触及重写的方法。我在“==”、“!=”、“Equals”和“GetHashCode”上放置了中断,并且在评估“value != mySearchCriteria”语句时没有调用它们。

就像它完全跳过了评估它一样。

I have a property in a composite control that checks to see if the value has changed prior to actually setting the related private field and doing a few other things.

However, it appears that it is never evaluating the statement.

Here is the code for the property:

public T SearchCriteria
        {
            get
            {
                return mySearchCriteria;
            }
            set
            {
                if (value != mySearchCriteria)
                {
                    mySearchCriteria = value;
                    EnsureChildControls();
                    SearchGridParser parser = SearchGridParserFactory.GetParser(this.Type);
                    parser.SetSearchPanelControls<T>(this.mySearchCriteria, ref mySearchParametersPanel);
                    GridView.PageIndex = 0;
                }
            }
        }

I have stepped through the code, and everytime it gets to "value != mySearchCriteria" it evaluates to false and skips the code inside the if statement. In fact, it does this even when I change it to "value == mySearchCriteria".. if just completely skips it no matter how it evaluates!

What the hey?

I've tried changing the order of the arguments in the check, and also using object.Equals() but none of these changes have made any difference.

I have overridden Equals, !=, == and GetHashCode.

There are other places in the code where it uses the "==" and "!=" for these object types without a problem, so I know that my overriding is working correctly.

Problem is, this never even hits the overriden methods. I put breaks on "==", "!=", "Equals" and "GetHashCode" and none of them are being called when the "value != mySearchCriteria" statement is being evaluated.

It's like it completely skips evaluating it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

若水微香 2024-10-07 19:08:06

在泛型类型之间使用 == 几乎总是一个坏主意。运算符是重载而不是覆盖,因此即使实际类型上存在 == 运算符,编译器也不会知道它。 (这意味着您声称“覆盖”了 ==!= 已经不正确 - 您已经重载了这些运算符。您应该确保您理解其中的区别,因为它非常重要。)

当你写:

代码中的其他地方对这些对象类型使用“==”和“!=”没有问题,所以我知道我的覆盖工作正常。

我怀疑这些区域不在通用代码中......它们是编译器知道正在比较什么类型的地方,因此知道使用您的重载。这与您的一般情况非常不同,在一般情况下,编译器不知道 == 使用什么,因此会退回到引用标识。

我假设您有一个 where T : class 的通用约束,否则您的代码根本无法编译 - 但它仍然只是执行引用比较,而不是使用实际提供的任何重载T 的类型。

使用 EqualityComparer.Default.Equals(value, mySearchCriteria) 来使用 Equals 的重写实现,包括 IEquatable

Using == between generic types is almost always a bad idea. Operators are overloaded rather than overridden, so even if there is an == operator on your actual types, the compiler won't know about it. (That means your claim that you've "overridden" == and != is already incorrect - you've overloaded those operators. You should make sure you understand the difference, as it's very important.)

When you write:

There are other places in the code where it uses the "==" and "!=" for these object types without a problem, so I know that my overriding is working correctly.

I suspect those areas aren't in generic code... they're where the compiler knows what types are being compared, so knows to use your overloads. That's very different from your generic situation, where the compiler doesn't know what to use for ==, so falls back to reference identity.

I assume you have a generic constraint of where T : class or your code wouldn't compile at all - but it's still just going to perform a reference comparison, instead of using whatever overload is provided by the actual type of T.

Use EqualityComparer.Default<T>.Equals(value, mySearchCriteria) to use overridden implementations of Equals including IEquatable<T>.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文