C# 3.0 使用从内部返回语句

C# 3.0 使用从内部返回语句,c#-3.0,C# 3.0,这将返回一个IEnumerable数据行。问题是,由于返回在using语句中,它的属性是否会处理IDB命令?我知道我可以很容易地重构它,因此我在使用之外更改了数据集的范围,但这比其他任何东西都更令人惊奇。是的,如果正确地处理IDbCommand,这将如预期的那样工作。编译器将把using块转换为try-catch-finally,在finally块中调用Dispose。您的IDbCommand对象的范围非常清楚:在括号{和}之间。一旦程序流从那里退出,对象就被释放。是的,DB命令将被释放,目前为

这将返回一个IEnumerable数据行。问题是,由于返回在using语句中,它的属性是否会处理IDB命令?我知道我可以很容易地重构它,因此我在使用之外更改了数据集的范围,但这比其他任何东西都更令人惊奇。

是的,如果正确地处理
IDbCommand
,这将如预期的那样工作。编译器将把using块转换为
try-catch-finally
,在
finally
块中调用
Dispose

您的
IDbCommand
对象的范围非常清楚:在括号
{
}
之间。一旦程序流从那里退出,对象就被释放。

是的,DB命令将被释放,目前为止一切正常

你可能会在IEnumerables上遇到麻烦。因为这些项可能是在从IEnumerable获取时生成的,而不是在创建IEnumerable时生成的,这就是它的本质。因此,这取决于如何实现
ds.Tables[0].AsEnumerable()
。它可以等待执行命令,直到您获得第一项。这在调用代码中,在using块之外。您将得到一个错误,因为该命令已被释放

这在这里可能不是问题,但从using块返回IEnumerables(或lambda表达式)时应始终考虑:

  using (IDbCommand command = new SqlCommand())
         {
             IDbDataAdapter adapter = new SqlDataAdapter();
             DataSet ds = new DataSet();
             adapter.SelectCommand = command;
             command.Connection = _dataAccess.Connection;
             command.CommandType = CommandType.StoredProcedure;
             command.CommandText = "GetProcData";
             command.Parameters.Add(new SqlParameter("@ProcID  ", procId));

            adapter.Fill(ds);
            return ds.Tables[0].AsEnumerable();
         }

当访问第一项时,
a
已被释放,您会得到一个错误。

正确地释放了
idb命令。根据经验,从using语句中返回时,只要满足以下条件,就可以这样做:

  • 您要返回的内容不在using子句中 声明
  • 返回的对象不是using语句块中创建的引用
  • 在第一种情况下,using语句将处理您试图返回的内容,在第二种情况下,变量将超出范围

    e、 g

    这里,
    using(){…}
    语句是我们的朋友。当我们退出块时,我们的
    SmtpClient
    被释放,结果条件仍然存在,供您使用

    然而,假设我们正在编写一个WinForm应用程序或WPF应用程序,并且我们在数据上下文周围包装了一个using块,那么当上下文在控件可以使用它之前消失时,我们就会产生一个问题

    //this is fine as result is createsd outside the scope of the block. 
    bool result = false;
    using (SmtpClient mailClient = new SmtpClient())
    {
        try
        {
            mailClient.Send(...);
            result = true;
         } 
         catch(SmtpException)
         {
             result = false;
         } 
         finally 
         {
             return result;
         }
    }
    
    在这里,
    using(){…}
    语句伤害了我们。当我们将客户数据绑定到GridView(或其他类似的数据绑定控件)时,我们已经处理了
    DbContext
    这一事实将意味着我们的表单没有绑定的对象,因此它将抛出异常


    HTH

    我也是这么想的,但我不确定。谢谢你的确认!
    //this is fine as result is createsd outside the scope of the block. 
    bool result = false;
    using (SmtpClient mailClient = new SmtpClient())
    {
        try
        {
            mailClient.Send(...);
            result = true;
         } 
         catch(SmtpException)
         {
             result = false;
         } 
         finally 
         {
             return result;
         }
    }
    
    // this will fail when you bind the customers to a form control!
    using (DbContext context = new DBContext())
    {
    context.Customers.Where(c => c.Name.Contains("Bob")).Load();
    return context.Customers.Local;
    }