可以显式调用“运算符 true()”吗?什么时候用于转换为布尔值
本文关键字:运算符 什么时候 用于 布尔值 转换 调用 true | 更新日期: 2023-09-27 18:30:28
好奇,我探索了 C# 中的重载运算符。Eric Lippert有一篇有趣的文章,讨论了C++和C#中关于operator&&
的设计决策。在C#中,它的重载是通过重载operator&
加上重载布尔运算符true
和false
来隐式定义的,这允许语言保留有时基本的短路语义。
玩弄有点异国情调的operator true()
和false()
我发现我无法直接打电话给他们。相反,它们在某些需要布尔值的地方被隐式调用。据我所知,这些是直接需要布尔值的语言结构,即三元条件运算符和 if 子句,加上对 operator&&
resp 的调用。 ||
当参数类型具有重载运算符时&
|
.
编辑:《C#编程语言》(7.11)一书以及14.11.2中带注释的C#标准 - 都是通过谷歌搜索结果找到的 - 有一个带有直接运算符调用的代码示例,我不明白一定是伪代码。我试图复制这一点。
顺便说一句,引发对operator false()
的调用更难;三元条件和if子句总是通过调用operator true()
来测试。似乎唯一的称呼方式就是称呼operator||()
.
显式调用布尔运算符的动机是,最好只直接定义其中一个并据此定义另一个运算符,以便定义始终保持一致。下面是一个小示例程序,其中包含我尝试过的一些内容。有没有我错过的语法?
using System;
namespace TriviallyTrue
{
public class T
{
public static bool operator true(T t) { Console.WriteLine("In op. true"); return true; }
public static bool operator false(T t) { return true; }
}
class Program
{
static void Main(string[] args)
{
T t = new T();
// bool b = T.true(t); // Identifier expected; 'true' is a keyword
// ok, I see. Let's use the keyword syntax.
// bool b = T.@true(t); //'TriviallyTrue.T' does not contain a definition for 'true'
// That's so not true!
// oh. perhaps we need to use cast syntax, akin to invoking operator int()?
// bool b = (true)t; // ; expected
// hm. It's in T's namespace...
// bool b = (T.true)t; // Identifier expected;
// we know that.
// another cast try.
// bool b = (T.@true)t; // The type name 'true' does not exist in the type 'TriviallyTrue.T'
// ah, a type is expected. Well, the type is bool, right? But casting to bool
// doesn't work either, see below and in Main().
// bool b = (T.@bool)t; // The type name 'bool' does not exist in the type 'TriviallyTrue.T'
// well, it exists *some*what
if (t) // works
{
// Console.WriteLine("t was " + (bool)t); // Cannot convert type 'TriviallyTrue.T' to 'bool'
// That's so not true!
Console.WriteLine("t was " + (t ? "True" : "False" )); // works!
}
}
}
}
示例会话:
In op. true
In op. true
t was True
我无法回答标题中的问题,但我想我可以涵盖这部分
显式调用布尔运算符的动机是,最好只直接定义其中一个并据此定义另一个运算符,以便定义始终保持一致。
在不以任何方式质疑Lippert@Eric写的内容的情况下,当true
或false
之一在逻辑上与另一个相反时,C#有一种更简单的方法来完成所有这些工作,这是最常见的实际情况。与其覆盖 4 个运算符(false
、true
、&
和 |
),不如简单地提供对 bool
的单个隐式转换。
例如
public class T
{
public static implicit operator bool(T t) { return t != null; }
}
现在所有这些工作
T a = new T(), b = null;
if (a) { }
if (!a) { }
if (b) { }
if (!b) { }
if (a && b) { }
if (b && a) { }
if (a & b) { }
if (a || b) { }
if (b || a) { }
if (a | b) { }
var c1 = a ? 1 : 0;
var c2 = b ? 1 : 0;
不能在 C# 中显式调用任何运算符方法。 operator true
和operator false
也不例外。只是大多数运算符方法都有更直接的隐式调用方法。
如果在其他方案中调用运算符方法而不是作为重载运算符有意义,请改为将其作为常规方法提供。它通常更具可读性,并且可以很好地避免您想要解决的多个单独实现的整个问题。
public class T
{
private bool asBoolean() { ... } // or even make it public
public static bool operator true(T t) { return t.asBoolean(); }
public static bool operator false(T t) { return !t.asBoolean(); }
}
为了完整起见,您可以实现operator false
public static bool operator false(T t) { return t ? false : true; }
但请不要这样做,除非你绝对需要。