【问题标题】:Can't cast int to bool不能将 int 转换为 bool
【发布时间】:2011-09-28 02:48:19
【问题描述】:

我面临的问题是 C# 无法将数字 1 转换为 bool。在我的情况下,(bool)intValue 不起作用。我得到一个InvalidCastException。我知道我可以使用Convert.ToBoolean(...),但我只是想知道它不起作用。对此有何解释?

我的代码是

if (actualValueType.Name == "Boolean" || setValueType.Name == "Boolean")
{
   if ((bool)actualValue != (bool)setValue)
   ...
}

【问题讨论】:

  • intbool 在 C# 中是完全不同的东西,而 C# 以强类型语言而闻名。
  • 为什么不直接写myvar != 0
  • 另外,为什么不直接检查actualValue is bool && setValue is bool?

标签: c# casting int boolean


【解决方案1】:

在其他语言中,false 等价于 0,true 等价于 1,但这在 C# 语言中是不可能的。

【讨论】:

  • 我知道这一点。问题是:为什么?!
  • @Jacob:实际上,在大多数语言中,false 等于 0,true 等于任何非零值。
  • @Yuck 我想知道他是否真的是对的。我同意你的看法!
  • @theknut - 因为 bool 是真或假的类型,而不是带有真实性的整数类型。
  • 我明白了。但是仍然......我只是想知道他们为什么不能实现它。它不是在真实性上打耳光。 if else 的实现很简单,不是吗?
【解决方案2】:

无需投射:

bool result = intValue == 1;

来自文档:

bool 的包含使得编写自文档代码更容易

一个布尔值是真或假

1.2.1 Predefined Types (C#)

【讨论】:

  • @theknut if ((actualValue>0) != (setValue>0)),假设 int > 0 = trueint < 0 = false
  • 实际上正确的是bool result = intValue != 0;,因为 False 是 1 而 True 除了 0 之外的所有内容。
  • @shadow 我认为您的意思是“False 为 0,除 0 外的所有内容均为 True”,而不是“False 为 1,除 0 之外的所有内容均为 True”
【解决方案3】:

在 C# 中,bool 实际上是 Boolean struct,因此它在内部不只是表示为 1 或 0。似乎该语言的创建者对该语言整体采用了一种显式而非隐式的方法。要完成您想做的事情(有效地将 1 转换为 true 和 0 到 false),请执行以下操作:

if (intValue == 1) {
    // do something
} else if (intValue == 0) {
    // do something else
} else {
    // invalid bool
}

你也可以去掉最后一个 else 子句,做典型的 C 语言的事情,让 intValue == 0 等价于 false,其他任何东西都是 true

【讨论】:

    【解决方案4】:

    intbool 不能隐式转换(例如,与 C++ 相比)。

    这是语言设计人员做出的明智决定,以便在条件中使用数字时避免代码出错。条件需要明确地采用boolean 值。

    不能写:

    int foo = 10;
    
    if(foo) {
      // Do something
    }
    

    想象一下,如果开发人员想将 foo 与 20 进行比较,但错过了一个等号:

    if(foo = 20) {
      // Do something
    }
    

    上面的代码将编译并工作 - 副作用可能不是很明显。

    switch 进行了类似的改进:您不能从一种情况转到另一种情况 - 您需要明确的breakreturn

    【讨论】:

    • 但是我得到一个异常抛出...不是更好得到一个编译器错误吗?除此之外,为什么我会在另一个程序中失败 switch(var) { case "bla": case "bla2": break;默认值:中断; }
    • 在你的 switch 中,你刚刚为一个代码块分配了 2 个 case - 我说的是 switch(x) { case "A": Console.Write("A");案例 "B": Console.Write("B");休息; }。 C++ 等效项将在控制台中打印“AB”。
    • 编译器异常比不抛出异常的运行时错误要好,如果int 值可转换为bool,则if (foo = 20) 就是这种情况。通过编译器异常,您可以立即了解问题并修复您的代码。由于运行时错误,您可能会花费数小时或数天时间试图弄清楚为什么您的 if 块总是运行,即使 foo 不等于 20。
    • 我得到一个运行时异常,而不是一个编译器错误,这会更好。这就是我想说的。
    • @theknut - 这是因为您正在执行只能在运行时检查的强制转换。编译器在编译时没有足够的信息来帮助您解决您的问题。
    【解决方案5】:

    可能在这里重复其他人,但您不能将 int 转换为 bool,因为 int 不是 bool。它是一个整数。谁曾想到? ;-)

    您需要根据您的 int 值创建一个新的 bool,并且已经发布的“myvar != 0”似乎已经足够了。

    还有你从​​哪里得到你的例外?运行以下代码肯定会产生编译器错误:

    int myIntValue = 0;
    bool myBoolValue = (bool)myIntValue;
    

    您必须做一些您的问题中未显示的通用内容。

    【讨论】:

    • 根本没有通用的东西。它与上面看到的代码相同。 setValue 为 1 且 actualValue 为真。在运行期间我得到了异常。
    • 如果 setValue 被声明为 int 你应该在 (bool)setValue 行中得到一个编译器错误! “无法将类型 'int' 转换为 'bool'” - 请发布完整的方法(包括变量声明)
    • setValue 是对象。这就是编译器不会带来错误的原因。
    • 我明白了。像这样修复您的代码: if (actualValueType.Name == "Boolean" && setValueType.Name == "Boolean")
    • 不,我没有。功能将丢失。我想知道其中一个是否是布尔值。
    【解决方案6】:
    bool b = Convert.ToBoolean(0);
    

    会将 0 和 null 转换为 false,将其他任何值转换为 true。

    【讨论】:

      【解决方案7】:

      "在其他语言中,false 等价于 0,true 等价于 1,但这在 C# 语言中是不可能的。"

      我不得不承认我认为 false 是零,而 true 是 !false....

      int fred = 2;
      
      if (fred == true)
      {
          printf("fred is true");
      }
      

      肯定会打印fred是真的

      【讨论】:

        【解决方案8】:

        如果你想将两个值变量转换成 bool 像 var 一样持有(1 和 2 并且想要返回 1 代表 false 和 2 代表 true )我建议:

        //in the end of method or something :
        return w == 2;
        

        【讨论】:

          【解决方案9】:

          您可以使用如下所示的三元运算符,而不是强制转换。 布尔 b = 真; int i = 1;

          // bool to int
          i = b == true ? 1 : 0;
          // int to bool
          b = i > 0 ? true : false;
          

          【讨论】:

            【解决方案10】:

            如果您只想不必在if (foo != 0) 中输入!= 0,您可以为int 类型创建一个扩展方法并执行if (foo.IsNonZero()) 之类的操作。

            如果 C# 允许扩展属性,您将能够编写不带括号的 if (foo.IsNonZero),在我看来,这比原来的 if (foo != 0) 读起来更清楚,但遗憾的是,目前情况并非如此。

            不过,无论哪种方式,您都可能会更好地使用之前建议的 Convert.ToBoolean(foo)

            【讨论】:

              【解决方案11】:

              出于学习目的,我正在寻找路径。我需要随机阻止一些节点作为可行走/阻塞。

              这是我想出的一个简单的解决方案:

              int block = Random.Range(0, 10) + 1;
              node.blocked = (block % 2 == 0) ? true : false;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2017-07-17
                • 2017-02-24
                • 1970-01-01
                • 2015-12-01
                • 2014-09-19
                • 1970-01-01
                • 2016-11-29
                • 2012-01-14
                相关资源
                最近更新 更多