如何覆盖`is`运算符

Col*_*ler 16 c#

我们知道:

int? number = 10;
Console.WriteLine(number is int); // true
Run Code Online (Sandbox Code Playgroud)

但:

NotNull<string> text = "10"; // NotNull<> is my struct
Console.WriteLine(text is string); // false
Run Code Online (Sandbox Code Playgroud)

我想要text is string回归真实,我该怎么做?

--------------------------------编辑

这是我的NotNull:

public class NotNull<T> where T : class
{
    public T Value { get; }

    private NotNull(T value)
    {
        this.Value = value;
    }

    public static implicit operator T(NotNull<T> source)
    {
        return source.Value;
    }

    public static implicit explicit NotNull<T>(T value)
    {
        if (value == null) throw new ArgumentNullException(nameof(value));
        return new NotNull<T>(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果一个类声明如下:

public class A
{
    public NotNull<string> B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我只希望任何序列化程序都可以序列化和反序列化它,如下所示:

public class A
{
    public string B { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

--------------------------------编辑2

我发现这是一个不可能的问题:

  1. 如果NotNull<>是类,default(NotNull<>)则为null,我什么都不做.
  2. 如果NotNull<>是struct,default(NotNull<>).Value则为null.

抱歉这个问题.

Nej*_*lof 16

在MSDN上,您有可重载运算符列表:可 重载运算符(C#编程指南)

这些运算符不能重载:

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

  • 鉴于你的问题是**"如何覆盖`是'操作员'**,我觉得你不清楚负担,OP. (10认同)

Jak*_*rtz 8

正如其他人已经指出的那样,is 不能超载.如果你发布关于你的非可空字符串的更多上下文,我们可以找到一些其他的解决方案.

is操作符对可空类型和它们的基础类型,不是因为它的超载,但由于这种行为在语言规范明确定义.在is评估时,可空类型被视为特殊情况.

您可以is在C#语言规范的7.10.10节中找到有关运算符的详细说明.以下是与可空类型相关的部分:

操作的结果E is T,其中E是表达式并且T是类型(...),其评估如下

•(...)

•否则,让D代表E的动态类型,如下所示:

  • (......)

  • 如果E的类型是可空类型,则D是该可空类型的基础类型.

•操作结果取决于D和T,如下所示:

  • (......)

  • 如果T是可空类型,如果D是T的基础类型,则结果为真.

  • 如果T是非可空值类型,则如果D和T是相同类型,则结果为真.