【问题标题】:Using various types in a 'using' statement (C#)在“使用”语句中使用各种类型 (C#)
【发布时间】:2009-06-08 17:53:00
【问题描述】:

既然 C# using 语句只是 try/finally{dispose} 的语法糖,为什么它只接受多个对象只有当它们属于同一类型时

我不明白,因为它们只需要 IDisposable。如果他们都实现了 IDisposable 应该没问题,但事实并非如此。

特别是我习惯写作

using (var cmd = new SqlCommand())
{
    using (cmd.Connection)
    {
        // Code
    }
}

我压缩成:

using (var cmd = new SqlCommand())
using (cmd.Connection)
{
    // Code
}

我想进一步压缩成:

using(var cmd = new SqlCommand(), var con = cmd.Connection)
{
    // Code
}

但我不能。我可能,有人会说,写:

using((var cmd = new SqlCommand()).Connection)
{
    // Code
}

因为我需要处理的只是连接而不是命令,但这不是重点。

【问题讨论】:

  • 我认为这实际上是一个好主意。我认为这只是尚未实施的东西。如果有一个不存在的实际具体原因,我会感到惊讶。不过我可能是错的......
  • 我在这里学到新东西了吗?上例中第二个未赋值的 using 语句是什么情况?该项目是否成为范围?
  • @spender: using 的参数需要是可以转换为 IDisposable 的表达式。声明就是(只有一个)这样的表达式。
  • @spender:是的,你(可能)学到了一些新东西。 using 的语法是 using(IDisposableInstance) 语句;。正如 Henk Holterman 所说,赋值是一种运算,其结果(通常未使用但在此使用)是赋值。
  • 受您的问题启发,我尝试了以下想法:stackoverflow.com/questions/974484/…

标签: c# types using


【解决方案1】:

你可以这样做:

using (IDisposable cmd = new SqlCommand(), con = (cmd as SqlCommand).Connection)
{
   var command = (cmd as SqlCommand);
   var connection = (con as SqlConnection);
   //code
}

也许这会让你满意。

【讨论】:

  • 这是迄今为止我见过的最接近的解决方法。但是,我需要将 cmd 转换回块中的 SqlCommand 才能对其进行操作。与“con”相同,我必须打开它才能完成我的工作。
  • @Andrei 你说得对,我会更新我的答案以反映你在说什么。
  • 这正是我的意思。我不认为这是对 using() using () { } 版本的改进
  • 是的,如果你以后必须把东西扔回去,那绝对比把它放在两行更糟糕。
  • @Henk 哦,我明白了。我同意。我也更喜欢自己使用堆叠的用法。我只是在回答他的问题,即你如何才能做他想做的事情。
【解决方案2】:

没有特别好的技术原因;我们本可以提出一种允许多个非同质类型声明的语法。鉴于我们没有,而且已经有一个非常好的、清晰、可理解和相当简洁的机制来声明嵌套使用不同类型的块,我们不太可能为了节省一些击键而添加新的语法糖。

【讨论】:

  • 哦,我明白了...为了保护我们免受句法糖尿病的侵害,我们不会再添加任何句法糖:P
  • 句法糖尿病.. muahah :)
  • 换句话说。呸! 耸肩
  • 但是等等,C# 中有很多东西可以“节省一些按键”。结合起来,它们都节省了大量的击键。越多越好! MSIL + 糖 = C#。
  • 除了这就是语法糖的重点——节省击键并使事情变得更容易。
【解决方案3】:

C#中的其他变量声明只允许你在同一个语句中声明多个相同类型的变量;我不明白为什么using 标头应该不同。

【讨论】:

  • 是和不是。没有什么能阻止你做:IComparable c1, c2;然后稍后在您的代码中使 c1 和 c2 成为实现 IComparable 的完全不同的具体类型。这就是 OP 所指出的,他们所需要的只是 IDisposable...
  • 当然可以,但是你也可以在 using 语句中使用 IDisposable,例如,这是合法的: using (IDisposable a = new SqlCommand(), b = new SqlConnection())
  • BFree,这正是 mquander 所说的,不是吗?使用 (IDisposable x = new Connection(), y = new Command()) 会起作用,但相当没用。引用计数的类型。
【解决方案4】:

我个人的使用方式可能符合要求:

private const string SQL_CONNECTION = "Your Connection String Here";

private void Test(string sqlCmd)
{
  using (var cmd = new SqlCommand(sqlCmd, new SqlConnection(SQL_CONNECTION)))
  {
    cmd.Connection.Open();
    cmd.ExecuteNonQuery();
    cmd.Connection.Close();
    // Close() is not really necessary.
    // Dispose will Close the connection.
  }
}

不,这不是using 子句在一行中的两个实例,但它与您在示例中尝试的一样紧凑。

此外,您可以通过将连接字符串转换为私有属性来使其更加紧凑和程序员友好:

private SqlConnection OpenConnection
{
  get {
    var con = new SqlConnection(SQL_CONNECTION);
    con.Open();
    return con;
  }
}

现在,Test() 中上面的第一段代码可以缩短为:

private void Test2(string sqlCmd)
{
  using (var cmd = new SqlCommand(sqlCmd, OpenConnection))
  {
    cmd.ExecuteNonQuery();
  }
}

这使得编码非常好。

【讨论】:

    猜你喜欢
    • 2023-01-23
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 2015-10-20
    • 2015-03-26
    • 2016-06-05
    相关资源
    最近更新 更多