【问题标题】:How can I change a bool to a 0 or a 1, can I cast it?如何将 bool 更改为 0 或 1,我可以转换它吗?
【发布时间】:2019-08-29 15:11:42
【问题描述】:

我有这个方法:

public void UpdatePhrase(PHRASE phraseColumn, bool value, string phraseId) 
{
   sql = string.Format("UPDATE Phrase SET " + phraseColumn.Text() + " = {0} WHERE PhraseId = '{1}'", value, phraseId);
        App.DB.RunExecute(sql);
}

它无法正常工作,因为我似乎需要 {0} 的值必须是 0 或 1。

有没有一种简单的方法可以取值并将其更改为 0 或 1?

【问题讨论】:

  • 或使用短语?1:0
  • 有点 OT 但是,不要这样创建 SQL 查询,它们容易被 SQL 注入。
  • 没有比使用参数更好的方法了。抱歉,您的 App.DB.RunExecute(sql); 似乎无法接收参数。您需要在这里进行一定程度的重构
  • @phuzi 建议人们使用参数是从不 OT...(只要问题确实与 SQL 相关,我想...)

标签: c#


【解决方案1】:

只要value ? 1 : 0,就这么简单!

【讨论】:

    【解决方案2】:

    @Sean 已经为您提供了解决问题的自然方法,但是,在我看来,您真正需要做的是重构您的 App.Db.RunExecute 以接收参数,所以你可以写

    public void UpdatePhrase(PHRASE phraseColumn, bool value, string phraseId) 
    {
       sql = "UPDATE Phrase SET " + phraseColumn.Text() + " = @v WHERE PhraseId = @id";
       List<SqlParameter> prms = new List<SqlParameter>
       {
          new SqlParameter {ParameterName = "@v", SqlDbType = SqlDbType.Boolean, Value = value},
          new SqlParameter {ParameterName = "@id", SqlDbType = SqlDbType.NVarChar, Value = phraseId}
       };
       App.DB.RunExecute(sql, prms);
    }
    

    这将部分消除 Sql 注入问题(我说部分是因为如果它的值来自用户输入,phraseColumn.Text() 仍然是问题的根源)

    现在 RunExecute 应该改为

    void RunExecute(string sqlCommand, List<SqlParameter> prms = null)
    {
         // usual code to open connection and create a command
         ......
    
         // If the caller passes a parameters list, add them to the command
         if(prms != null)
            cmd.Parameters.AddRange(prms.ToArray());
    
         // Now execute the command
         cmd.ExecuteNonQuery();
    }
    

    RunExecute 的更改使用了一个可选参数,因此您当前的代码不会受到新参数的影响,但从现在开始您将能够编写更好的 Sql 代码。

    【讨论】:

    • 我想知道投反对票的原因。如果这个答案有问题,我认为我们都需要知道并避免它。
    • 很好的答案。这不仅有助于回答 OP 的问题,将 SqlParameters 添加到列表中然后使用 cmd.Parameters.AddRange(list.ToArray()) 是一个新概念(对我来说),它似乎非常有用和干净:+1
    • 我认为投反对票的原因是您实际上没有回答问题,现在是将布尔值转换为 1 或 0。虽然您的回答提供了一个很好的例子使用参数化查询它不会解决原始问题。
    • 你有一个观点@Sean。我没有回答这个问题,因为我们这里已经有 3 个答案来解释如何将布尔值转换为整数。 (还有两个只是你的一个坏副本)。再次重复第一个自然修复对我来说毫无意义。所以我认为为了让我的回答更好,我只需要承认你的工作。
    【解决方案3】:
    value ? 1 : 0
    

    如@Sean 回答或

    Convert.ToInt32(value)
    

    ToInt32(Boolean) 将指定的布尔值转换为 等效的 32 位有符号整数。

    【讨论】:

      【解决方案4】:

      你可以使用int count = updateCommand.ExecuteNonQuery;所以if count&gt;0,这意味着我们的任务完成了1(真),否则0(假)

      updateCommand.Parameters.AddWithValue("@Var" , "Johne");
      
          try
          {
              connection.Open();
              int count = updateCommand.ExecuteNonQuery;
              if (count > 0)
                  return true;
              else
                  return false;
          }
          catch (SqlException ex)
          {
              throw ex;
          }
          finally
          {
              connection.Close();
          }
      }
      

      希望你明白了^_^。

      【讨论】:

        【解决方案5】:

        你可以这样做(布尔值上的 GetHashCode 返回一个常数 1/0,不计算):

        true.GetHashCode() // 1
        false.GetHashCode() // 0
        

        【讨论】:

          【解决方案6】:
          public void UpdatePhrase(PHRASE phraseColumn, bool value, string phraseId) 
          {
             sql = string.Format("UPDATE Phrase SET {phraseColumn} = {value ? 1 : 0} WHERE PhraseId = '{phraseId}'");
                  App.DB.RunExecute(sql);
          }
          

          但这可能会受到 SQL 注入攻击,因此最好将其编写为参数化查询。

          【讨论】:

          • (int)value 甚至不会编译
          • 没错,我在 C 中思考了一会儿。固定。
          【解决方案7】:

          对于需要极致性能的场景,您可以使用System.­Runtime.­CompilerServices.­Unsafe 包直接内联执行此转换。这将导致本机代码不包含分支或函数调用。

          using System.Runtime.CompilerServices;
          
          /// ...
          
          bool _bool;
          byte _byte;
          
          _bool = true;
          _byte = Unsafe.As<bool, byte>(ref _bool);
          Console.WriteLine(_byte);           //  -->  1
          
          _bool = false;
          _byte = Unsafe.As<bool, byte>(ref _bool);
          Console.WriteLine(_byte);           //  -->  0
          

          您也可以使用此方法设置一个ref local byte 变量,该变量存在性地表示Boolean瞬时身份,但被视为byte .这对于使用 { 0, 1 } 解释持续监控不断变化的 { false, true } 可能很有用。

          class Program
          {
              static bool _bool;
          
              static void Main()
              {
                  Task.Factory.StartNew(() => { while (true) _bool = !_bool; });
          
                  // define a "ref local" that persistently views Boolean value '_bool' as a byte
                  ref byte _byte = ref Unsafe.As<bool, byte>(ref _bool);
          
                  while (true)
                      Console.Write(_byte + " ");
              }
          };
          

          如果您不熟悉 ref,那么只要显示此技术,只要值更改,就不会涉及任何类型的“更新”或“转换”,因为 ref byte 实际上只是一个原始Boolean 实体本身的不同“视图”。

          输出有点令人着迷。

          【讨论】:

            猜你喜欢
            • 2011-12-16
            • 1970-01-01
            • 2020-03-12
            • 1970-01-01
            • 2022-12-28
            • 2021-08-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多