我一直在寻找结构的压倒一切的指导方针,但我能找到的只是类。
起初我以为我不必检查传递的对象是否为空,因为结构是值类型并且不能为空。但现在我开始考虑它,因为 equals 签名似乎
public bool Equals(object obj)
没有什么可以阻止我的结构的用户尝试将它与任意引用类型进行比较。
我的第二点涉及在比较结构中的私有字段之前我(认为我)必须进行的转换。我应该如何将对象转换为我的结构类型? C# 的 as
关键字似乎只适合引用类型。
I've looked for overriding guidelines for structs, but all I can find is for classes.
At first I thought I wouldn't have to check to see if the passed object was null, as structs are value types and can't be null. But now that I come to think of it, as equals signature is
public bool Equals(object obj)
it seems there is nothing preventing the user of my struct to be trying to compare it with an arbitrary reference type.
My second point concerns the casting I (think I) have to make before I compare my private fields in my struct. How am I supposed to cast the object to my struct's type? C#'s as
keyword seems only suitable for reference types.
发布评论
评论(6)
感谢模式匹配的引入在 C# 7.0 中,有一种更简单的方法来完成可接受的答案:
您还可以将其作为表达式主体函数使其变得更短:
Thanks to pattern matching introduced in C# 7.0 there is an easier way to accomplish the accepted answer:
You could also make it even shorter as an expression-bodied function:
我想,如果使用 .NET 4.5,则可以使用 文档:
I suppose, if one's using .NET 4.5, one can use the default implementation as noted in the documentation:
如果有人想知道将结构装箱到 Nullable 对象中对性能的影响(以避免
is
和强制类型转换的双重类型检查),那么有一个不可忽略的问题开销。tl;dr:使用
is
&在这个场景中投射。结果:
警告:尽管我确实验证了基准代码本身并未以奇怪的方式进行优化,但该测试可能在很多方面存在缺陷。
查看 IL,双重检查方法编译得更干净一些。
拳击 IL:
仔细检查 IL:
支持 Roman Reiner,因为他发现了一个确实让我看起来不太好的错误。
In case anyone's wondering about the performance hit of boxing the struct in a Nullable object (to avoid the double type check from
is
and the cast), there is a non-negligible overhead.tl;dr: Use
is
& cast in this scenario.Results:
Warning: This test might be flawed in many ways, though I did verify that the benchmark code itself wasn't optimized in an odd fashion.
Looking at the IL, the double-check method compiles a little cleaner.
Boxing IL:
Double-check IL:
Props to Roman Reiner for spotting a mistake that really wasn't making me look good.
使用
is
运算符:Use the
is
operator:添加到现有答案。
如果附加 ?,您仍然可以拥有可为空的值。在结构名称之后(这适用于每个值对象)
也可以通过调用
(MyStructName)variableName
来完成转换Adding to the existing answers.
You can still have nullable values if you append a ? after the struct name (this works for every value object)
Casting is done also by calling
(MyStructName)variableName