C# 空合并操作符(??)不可重载?其实有黑科技可以间接重载!

栏目: C# · 发布时间: 6年前

内容简介:在微软的官方 C# 文档中,此操作符被定义为不可重载。不过我们有方法可以间接实现这样的重载。你可以阅读

?? 操作符叫做 null-coalescing operator,即 null 合并运算符。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数。

在微软的官方 C# 文档中,此操作符被定义为不可重载。不过我们有方法可以间接实现这样的重载。

运算符重载

你可以阅读 C# 中那些可以被重载的操作符,以及使用它们的那些丧心病狂的语法糖 了解 C# 中提供的所有可以重载的操作符。在此文中, ?? 被明确定义为不可重载。

你更可以在微软官方文档中找到这样的说法:

=, ., ?:, ??, ->, =>, f(x), as, checked, unchecked, default, delegate, is, new, sizeof, typeof

These operators cannot be overloaded.

这些运算符无法进行重载。

编写 NullableString 的 ?? 重载

我们先写一个空壳子。连构造函数都是 private 的,这个类当然几乎不可用啦。

特别注意,我们的 Walterlv.NullableString 用的是 struct 类型,这样能与 Nullable<T> 的用法上接近。也就是说,我们可以确保其值实际上永不为 null。

namespace Walterlv
{
    public struct NullableString
    {
        private readonly string _value;

        private NullableString(string value)
        {
            _value = value;
        }
    }
}

现在我们挑战一下官方说好了不能重载的 ?? 重载(作死):

C# 空合并操作符(??)不可重载?其实有黑科技可以间接重载! ▲ 试着重载 ??

很明显,既不是可重载的一员运算符也不是可重载的二元运算符。

现在我们试试隐式转换:

public static implicit operator NullableString(string value)
{
    return new NullableString(value);
}

public static implicit operator string(NullableString nullableString)
{
    return nullableString._value;
}

然而这样的写法实际上并无实际用途。

但是,我们可以在 NullableString 后面加上 ?

public static implicit operator NullableString?(string value)
{
    return string.IsNullOrEmpty(value) ? (NullableString?) null : new NullableString(value);
}

public static implicit operator string(NullableString? nullableString)
{
    return nullableString?.ToString() ?? string.Empty;
}

也就是说,C# 竟然允许隐式转换的时候,参数和返回值都不是此类型。当然,实际上这只对 Nullable<T> 生效,如果你试图写别的类型,是不可以的。

为了方便,我们重写一下 ToString() ,部分场景下可以代替隐式转换,少写一些代码。

public override string ToString()
{
    return string.IsNullOrEmpty(_value) ? string.Empty : _value;
}

于是,我们的 NullableString 类型的完整代码如下:

namespace Walterlv
{
    public readonly struct NullableString
    {
        private readonly string _value;

        private NullableString(string value)
        {
            _value = value;
        }

        public static implicit operator NullableString?(string value)
        {
            return string.IsNullOrEmpty(value) ? (NullableString?) null : new NullableString(value);
        }

        public static implicit operator string(NullableString? nullableString)
        {
            return nullableString?.ToString() ?? string.Empty;
        }

        public override string ToString()
        {
            return string.IsNullOrEmpty(_value) ? string.Empty : _value;
        }
    }
}

注释就你自己添加吧。

一些注意事项

这里有一些好玩的事情需要分享。比如我们写出如下代码:

NullableString? value = "";
var value0 = value?.ToString();
var value1 = value.ToString();

你觉得 value0value1 分别会得到什么呢?

呃……

value0 得到 null ,而 value1 得到 ""

另外,如果你将一开始的初始值设为 null ,那又可以得到什么结果呢?

NullableString? value = null;
var value0 = value?.ToString();
var value1 = value.ToString();

一样的, value0 得到 null ,而 value1 得到 ""

另外,你可以从 null 强转出你需要的类:

var value = (NullableString?) null;

本文会经常更新,请阅读原文: https://walterlv.com/post/overload-null-coalescing-operator-in-csharp.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

C# 空合并操作符(??)不可重载?其实有黑科技可以间接重载! 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接:https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

神一样的产品经理

神一样的产品经理

闫荣 / 电子工业出版社 / 2012-6-1 / 79.00元

这是一本系统阐述移动与互联网产品从无到有、从有到优的产品经理实践案例著作。《神一样的产品经理:基于移动与互联网产品实践》贯穿着“人如产品,产品如人”、“产品的根基和源泉来自现实生活”的写作理念,表达了产品的成功需要神一样的产品经理管理的观点。 《神一样的产品经理:基于移动与互联网产品实践》由浅入深、循序渐进地阐述了产品经理、产品需求、用户体验、项目管理、产品运营和产品团队管理的内容,理论与实......一起来看看 《神一样的产品经理》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具