Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Nullable和基类型之间实现运算符-我应该这样做吗?_C#_Operator Overloading_Nullable - Fatal编程技术网

C# 在Nullable和基类型之间实现运算符-我应该这样做吗?

C# 在Nullable和基类型之间实现运算符-我应该这样做吗?,c#,operator-overloading,nullable,C#,Operator Overloading,Nullable,这可能是众所周知的,并且已经讨论过了,但令我惊讶的是,今天我发现您可以在nullables和它们的基类型之间给出自己的运算符实现 这意味着您可以拥有一个struct,它可以检查null,并返回true 现在,在我的情况下,这将是很方便的-根据的建议,我有一个包装字符串的结构。对我来说,能够直接将这个包装的字符串与null进行比较(而不是使用.IsNull或类似的值)要自然得多,这意味着从使用字符串更改为这些包装字符串通常不需要对代码进行其他更改 但是。。这个特性(我相信)鲜为人知,这与任何将st

这可能是众所周知的,并且已经讨论过了,但令我惊讶的是,今天我发现您可以在nullables和它们的基类型之间给出自己的运算符实现

这意味着您可以拥有一个
struct
,它可以检查
null
,并返回true

现在,在我的情况下,这将是很方便的-根据的建议,我有一个包装字符串的结构。对我来说,能够直接将这个包装的字符串与null进行比较(而不是使用.IsNull或类似的值)要自然得多,这意味着从使用字符串更改为这些包装字符串通常不需要对代码进行其他更改

但是。。这个特性(我相信)鲜为人知,这与任何将struct(它是)置于string(它所表示的)之上的人的直觉相反,而且它混淆了ReSharper(
structValue==null
警告“表达式总是错误的”)让我觉得这也许是一个肮脏的把戏留在肮脏但整洁的把戏橱柜里

所以我想知道,你会接受它吗?如果没有,请原谅我这样做。。还是最好不要走这条路



我坚信代码是自文档化的,并和之相适应。例如,“GETTES”不应该修改数据等。我会考虑将结构变量与NULL进行比较,乍一看比较混乱,所以我会避免它(不管它看起来多么方便)。如果您希望有很多人使用(或至少查看)您的代码,这一点尤其正确。

我认为您基本上与编译器为
Nullable
所做的相同。这也是一个结构,还可以检查它的
null
。所以我想,没关系。然而,我不会这么做。我不能提出替代方案,因为我目前看不到您的包装器添加的值…
StringWrapper
在实际代码中表示一个
InternedString
-这是一个字符串,如果它是相同的值,则保证是相同的实例。因此,
=
被实现为一个
对象。ReferenceEquals()
等等。现在可以检查
InternedString
是否为null就很好了,但是默认的比较将始终返回“false”,因为结构永远(通常)不等于(struct?)null。为什么需要这个?string类已经使用了类似的技术。为什么要使用struct呢?为什么不使用引用类型呢?默认情况下,string类不进行内部调用。如果您选择使用string.Intern,则会阻止收集该字符串,并且不会因为意外地将内部字符串与非内部字符串混合而获得任何类型安全性。此结构防止了这种情况(同时覆盖GetHashCode和Equals成为RuntimeHelper.GetHashCode和ReferenceEquals),从而实现更快的字典性能。至于我为什么要使用结构,我可以使用引用类型。但是,当您试图表示一个单一的、不可变的引用值时,为什么要使用引用类型呢。。。;如果(x==null){..}强制将
==(T,null)
选择为
null
不是
T
中的值,其中
T
是值类型,但隐式转换为
null
。我想它比
==(T,Object)
稍好一点,但它似乎有点狡猾。ReSharper正在使用(尽管是高级的)启发式方法——并且忽略了这种偷偷摸摸的方法。
public struct StringWrapper
{
    private readonly string str;
    public override string ToString() { return str; }

    public static bool operator ==(StringWrapper a, StringWrapper b) 
    { return a.str == b.str; }
    public static bool operator !=(StringWrapper a, StringWrapper b) 
    { return !(a == b); }
    public static bool operator ==(StringWrapper a, StringWrapper? b)
    {
        if (!b.HasValue || b.Value.str == null) return a.str == null;
        return a == (StringWrapper)b;
    }
    public static bool operator !=(StringWrapper a, StringWrapper? b) 
    { return !(a == b); }
    public static bool operator ==(StringWrapper? a, StringWrapper b) 
    { return b == a; }
    public static bool operator !=(StringWrapper? a, StringWrapper b) 
    { return !(a == b); }

    public StringWrapper(string str) { this.str = str; }
}