Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.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# 否定运算符(!)的重载应该有什么类型?_C#_Operator Overloading - Fatal编程技术网

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

C# 否定运算符(!)的重载应该有什么类型?,c#,operator-overloading,C#,Operator Overloading,如果我过载运算符,它应该返回什么类型?在一本书中,我发现了以下内容(部分列表): 事实上,我希望编译器要求运算符返回一个MyType。但事实并非如此 所以。。。为什么的返回类型不正确运算符必须是包含类型吗?您必须将++或-的返回类型设置为包含类型。假设我问您“串联的返回类型是什么”?你会怎么说?也许你会回头问“什么的连接?”链式连接是在字符、字符串、序列、可链式数据、语言、离散有限自动机和其他一千种事物上定义的,因此返回的类型由参数的类型决定。但串联的类型通常是参数的类型。不总是;例如,两个字符

如果我过载
运算符,它应该返回什么类型?在一本书中,我发现了以下内容(部分列表):

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

所以。。。为什么
的返回类型不正确运算符必须是包含类型吗?您必须将
++
-
的返回类型设置为包含类型。

假设我问您“串联的返回类型是什么”?你会怎么说?也许你会回头问“什么的连接?”链式连接是在字符、字符串、序列、可链式数据、语言、离散有限自动机和其他一千种事物上定义的,因此返回的类型由参数的类型决定。但串联的类型通常是参数的类型。不总是;例如,两个字符的串联就是一个字符串。但通常情况下

类似地,问题“什么是!运算符的类型?”完全取决于被否定的是什么,而您没有说您要否定的是什么。通常,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();
好的,否定MyBool的规则是什么?真变假,假变真,未知保持未知:

    public static MyBool operator !(MyBool b)
    { 
        if (b == True) return False;
        if (b == False) return True;
        return Unknown;
    }
在本场景中,将显示!接线员是MyBool

当然,由于C#2.0,我们有三值逻辑,形式为
Nullable
,但您可能需要更复杂的逻辑类型(或者您可能正在编写C#1.0代码)


很难给出合理的例子,说明否定一个Foo会导致一个Bar;某种“一元”工作流对象可能是一种情况——给定类型的对象的否定是另一种类型的对象,表示否定的延迟执行。

这个例子很糟糕。这是哪本书?我不想诋毁这本书的作者,所以我不想给这本书起名。我将向作者指出这个问题及其答案。如果作者已经出版了这本书,他必须准备好接受对书中表达的观点的批评。很可能这个特定的例子很糟糕,本书的其余部分也很好。在.Net框架中找到的
MyBool
的一个例子是。另请参见,尽管返回值文档在我看来似乎有点不合适。一个非人为的例子是,当将逻辑表达式表示为类型时,否定可能会产生不同的类型。例如,对LogicalOr对象应用否定(!)实际上可能返回LogicalNot。@LBushkin:的确,我考虑过去那里。如果您创建诸如True和False之类的类型,您实际上可以构建系统,强制编译器解决一些逻辑问题,以便对程序进行类型检查。通过构造这样一个程序,你可以证明C#程序的分析至少是NP难的。我认为这对于这个答案来说可能有点深奥。现在我开始想知道为什么你不能否定
int
。我认为5的反面是-5,那么为什么不能使用
!5
?@comecme:历史上,在C语言中没有“布尔”这个词。只有int!C语言中的约定是:零整数与“false”是同一事物,非零整数与“true”是同一事物。此外,int也可以被视为位数组。这就是为什么在C中的int上有三个否定运算符!执行逻辑求反,将整数视为布尔运算,~执行位求反,将整数视为位数组,—执行算术求反,将整数视为数字。如果这一切听起来很可怕,那是因为它很可怕。整数不是布尔。
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();
    public static MyBool operator !(MyBool b)
    { 
        if (b == True) return False;
        if (b == False) return True;
        return Unknown;
    }