我一直在重写一些旧代码,以便将using
语句用于我的DataTables,而不是每次都记住Dispose
:
using (DataTable dt = BLL.GetDataTable()) {
foreach(DataRow dr in dt.Rows) {
// iteration logic
}
}
但是在特定情况下,DataTable的内容基于变量而有所不同,因此我创建了初始DataTable,然后再分配值:
DataTable dt = new DataTable();
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
dt.Dispose();
将其更改为使用using
,我有:
using (DataTable dt = new DataTable()) {
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
}
这是一种好习惯吗(即使用empty
语句创建using
DataTable)?我不知道为什么,但是感觉不对。
答案 0 :(得分:5)
正如我在评论中所述,您的最后一个示例将不起作用。如果您想执行类似的操作,则可以将DataTable生成移到一个单独的函数中:
public DataTable GetBLLDataTable()
{
switch(foo)
{
case bar:
return BLL.GetDataTable(bar);
break;
default:
return BLL.GetDataTable();
break;
}
}
然后在using语句中使用此方法返回的DataTable:
using (DataTable dt = GetBLLDataTable()) {
// iteration logic here
}
答案 1 :(得分:4)
在最后一个示例中,您只处理第一个DataTable对象,而不处理另一个已分配的对象。
using
语句只是try/finally
的语法糖。您可以改写上一个示例,例如:
DataTable dt;
try
{
switch (foo)
{
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
}
finally
{
dt?.Dispose();
}
这将确保您的IDisposable
对象始终处于废弃状态。在这种情况下,这是一个很奇怪的示例,因为我不明白为什么要在DataTable
中分配一个switch
,然后立即将其丢弃。
答案 2 :(得分:2)
只是另一种方法,但与约翰所说的相似。您可以使用func<>
设置get方法并在using()
Func<DataTable> func = null;
switch (foo)
{
case bar:
func = () => BLL.GetDataTable(bar);
break;
default:
func = () => BLL.GetDataTable();
break;
}
using (var dt = func())
{
// iteration logic here
}
我个人更喜欢约翰斯的方法,它更具可读性。但是,所有操作都一样,因此您可以使用自己最喜欢的功能。