否定运算符(!)的重载应该是什么类型?

com*_*cme 5 c# operator-overloading

如果我!在一个类中重载操作符,它应该返回什么类型?在一本书中我找到了这个(部分列表):

public class MyType {
    public int IntField { get; set; }

    public MyType(int intField) {
        IntField = intField;
    }

    public static bool operator !(MyType mt) {
        return (mt.IntField <= 0);
}
Run Code Online (Sandbox Code Playgroud)

它确实编译,但我希望!运算符返回一个MyType实例,如

public static MyType operator !(MyType mt) {
    var result = new MyType(-mt.IntField);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

实际上,我希望编译器要求!运算符返回一个MyType.但事实并非如此.

那么......为什么!运算符的返回类型不必是包含类型?你必须做的返回类型++或者--是包含类型.

Eri*_*ert 11

假设我问你"连接的返回类型是什么"?你打算说什么?可能你转过身来问"串联什么?" 连接是在字符,字符串,序列,可连接的deques,语言,离散有限自动机和其他一千种事物上定义的,因此返回的类型由参数的类型决定.但通常,连接的类型是参数的类型.不总是; 例如,两个字符串联是一个字符串.但通常.

同样,问题是"运算符的类型是什么?" 完全取决于被否定的东西,你还没有说出你在否定的东西.通常,T的否定是另一个T,但它不一定是.

我怀疑你没有问正确的问题.我认为你应该问的问题是"你将超载!运算符的现实场景是什么?" 你从这本书中给出的例子是可怕的; 它没有激发为什么代码的作者完全覆盖运算符.

这是一个更现实的例子.假设我们生活在一个没有可空类型的世界里.您可能决定使用三值逻辑:

sealed class MyBool
{
    private MyBool() {} // No one creates it!
    public static MyBool True = new MyBool();
    public static MyBool False = new MyBool();
    public static MyBool Unknown = new MyBool();
Run Code Online (Sandbox Code Playgroud)

好吧,否定MyBool的规则是什么?True变为False,False变为True,Unknown将保持未知:

    public static MyBool operator !(MyBool b)
    { 
        if (b == True) return False;
        if (b == False) return True;
        return Unknown;
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,类型!运营商是MyBool.

当然,由于C#2.0我们有三值逻辑Nullable<bool>,但你可能想要更复杂的逻辑(或者你可能正在编写C#1.0代码).

很难想出一个合理的例子,其中否定一个Foo导致一个Bar; 某种"monadic"工作流对象可能是一种可能的情况 - 其中给定类型的对象的否定是表示否定的延迟执行的不同类型的对象.

  • @comecme:历史上在C语言中没有"布尔"这样的东西.只有int!C中的约定是,零int与"false"相同,非零int与"true"相同.此外,int也可以被视为位数组.这就是为什么在C中有三个否定运算符的原因!逻辑否定,将int作为bool处理,〜逐位否定,将int作为位数组处理,以及 - 算术否定,将int作为数字处理.如果这一切听起来很可怕,那是因为它很可怕.Ints不是bools. (3认同)
  • 在将逻辑表达式表示为类型时,否定可能产生不同类型的非人为例子.因此,例如,将否定(!)应用于LogicalOr对象实际上可能会返回LogicalNot. (2认同)