Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.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# 一个人能显式地调用`operator true()`吗?何时用于转换为布尔值?_C#_Boolean_Type Conversion_Operators - Fatal编程技术网

C# 一个人能显式地调用`operator true()`吗?何时用于转换为布尔值?

C# 一个人能显式地调用`operator true()`吗?何时用于转换为布尔值?,c#,boolean,type-conversion,operators,C#,Boolean,Type Conversion,Operators,出于好奇,我研究了C#中的重载运算符。有一个有趣的讨论C++和C语言中关于运算符和& < /代码>的设计决策。在C#中,它的重载是通过重载运算符&加上重载布尔运算符true和false来隐式定义的,这允许语言保留有时必要的短路语义 使用有点奇怪的操作符true()和false()我发现我无法直接调用它们。相反,它们在某些需要bool的地方被隐式调用。据我所见,这些是直接需要bool的语言结构,即三元条件运算符和if子句,加上对运算符&&resp的调用| |当参数类型具有重载运算符时 编辑:这本书

出于好奇,我研究了C#中的重载运算符。有一个有趣的讨论C++和C语言中关于<代码>运算符和& < /代码>的设计决策。在C#中,它的重载是通过重载
运算符&
加上重载布尔运算符
true
false
来隐式定义的,这允许语言保留有时必要的短路语义

使用有点奇怪的
操作符true()
false()
我发现我无法直接调用它们。相反,它们在某些需要bool的地方被隐式调用。据我所见,这些是直接需要bool的语言结构,即三元条件运算符和if子句,加上对
运算符&&
resp的调用<代码>| |当参数类型具有重载运算符时<代码>

编辑:这本书《C#编程语言》(7.11)以及14.11.2中的带注释的C#标准——都是通过谷歌搜索结果找到的——都有一个带有直接运算符调用的代码示例,我不理解这一定是伪代码。我试着复制它

另一方面,更难激发对
操作符false()的调用。
;三元条件子句和if子句始终通过调用
运算符true()
进行测试。似乎调用它的唯一方法是调用
操作符| |()

显式调用布尔运算符的动机是,最好只直接定义其中一个,然后根据它定义另一个,这样定义总是一致的。下面是一个小示例程序,其中有一些我尝试过的东西。有没有我遗漏的语法

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
不能在C#中显式调用任何运算符方法<代码>运算符true和
运算符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(); }
}

为了完整性,您可以实现
运算符false
,例如

public static bool operator false(T t) { return t ? false : true; }
但是,除非您绝对需要,否则请不要这样做。

在C#中不能显式调用任何运算符方法<代码>运算符true和
运算符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(); }
}

为了完整性,您可以实现
运算符false
,例如

public static bool operator false(T t) { return t ? false : true; }

除非你绝对需要,否则请不要回答。

我无法回答标题中的问题,但我想我可以涵盖这一部分

显式调用布尔运算符的动机是,最好只直接定义其中一个,然后根据它定义另一个,这样定义总是一致的

不必以任何方式质疑@Eric Lippert在那篇文章中所写的内容,当
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;

我不能回答标题中的问题,但我想我可以涵盖这一部分

显式调用布尔运算符的动机是,最好只直接定义其中一个,然后根据它定义另一个,这样定义总是一致的

不必以任何方式质疑@Eric Lippert在那篇文章中所写的内容,当
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;

最后一个建议很有趣。为什么不这样做?@PeterA.Schneider对我来说,它的可读性似乎要差得多,尤其是当你开始向类中添加更多运算符时。无论如何,我不能也不想阻止你这么做是的,特别是当引入到bool op的转换时,将不清楚执行哪些代码。但是,如果所有T都是真或假(当然,两个运算符不需要这样),从维护的角度来看,用另一个来定义一个似乎在逻辑上是合理的,特别是如果T(以及bool决策)可能会随着时间的推移而演变,我没有意识到,没有一个操作符可以显式调用,它们在C++中是如何调用的。偶数强制转换只是调用转换运算符的触发器。在这种情况下,我不能为
true()
false()
这样做的事实就不那么令人惊讶了;-)。最后一个建议很有趣。为什么不这样做?@PeterA.Schneider对我来说,它的可读性似乎要差得多,尤其是当你开始向类中添加更多运算符时。无论如何,我不能也不想阻止你这么做是的,尤其是当转换为布尔运算为intr时