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