是否有必要在using块内使用using块?

时间:2019-06-07 11:34:22

标签: c# .net

我有一些类似下面的代码。我在sql connection class块中使用我的using。完成工作后,它将按预期方式处理连接。我在同一个using块中也有一些内核类,我希望它们所在的using块完成工作时将它们丢弃。

我搜索了一下,但找不到答案。 using块是否处置了其块内的所有对象,还是只是处置了作为参数写入的对象?我希望我能正确地问。我只想了解,我不想继续用块写不必要的东西。

using (SqlConnection conn = new SqlConnection("server=" + serverName + ";initial catalog=" +
                                                      dataBase + ";integrated security=false;uid=" +
                                                      sqlUser + ";password=" + sqlPass + ";"))
{
    Kernel kernel = new Kernel();
    Sirket sirket = default(Sirket);
    Fatura fatura = default(Fatura);
    try
    {
        sirket = kernel.yeniSirket(TVTTipi.vtMSSQL,
                                      "vt adı",
                                      "vt kull adı",
                                      "vt kull sifre",
                                      "netsis kull adı",
                                      "netsis kull sifre",
                                      sube kodu);
        fatura = kernel.yeniFatura(sirket, TFaturaTip.ftSFat);
        fatura.OkuUst("A00000000000011", "C0001");
        fatura.OkuKalem();
        fatura.kayitSil();
    }
    finally
    {
        Marshal.ReleaseComObject(fatura);// those are releasing the objects. if i didn't use those methods would they get disposed immediately as using block finishes.
        Marshal.ReleaseComObject(sirket);
        kernel.FreeNetsisLibrary();
        Marshal.ReleaseComObject(kernel);
    }

}

4 个答案:

答案 0 :(得分:4)

不,using仅会处理一个对象。

但是,使用块嵌套可以这样写:

using (var con = new SqlConnection())
using (var kernel = new Kernel())
{
    // ...
} // Disposes kernel and con

请注意,COM对象不会与using一起释放。为此,您需要编写的finally块。只需将dispose调用放在这里。

另一个选择是包装器,它也可以释放COM对象。大纲:

class ComReleaseWrapper : IDisposable
{
    object _obj;
    public ComReleaseWrapper(object o) {
       _obj = o;
    }
    public object Object { get { return _obj; } }

    public void Dispose() {
        if (_obj != null) {
            Marshal.ReleaseComObject(_obj);
            if (_obj is IDisposable d) d.Dispose();
        }
        _obj = null;
    }
 }

 using (var kernelWrap = new ComReleaseWrapper(new Kernel()) {
    var kernel = kernelWrap.Object as Kernel;
 }

答案 1 :(得分:1)

它仅处理定义的变量,在这种情况下,该变量将为SqlConnection。如果有多个项目要处理,则可以按以下方式堆叠它们,以使代码更易于阅读:

using (var f1 = new FileStream(@"C:\temp\file.txt", FileMode.Open))
using (var f2 = new FileStream(@"C:\temp\file.txt", FileMode.Open))
using (var f3 = new FileStream(@"C:\temp\file.txt", FileMode.Open))
{
    //do stuff with filestreams here
}

答案 2 :(得分:1)

using块仅处理括号中初始化的对象。

using (var conn = new SqlConnection(connectionString))
{
    // Do all sort of stuff here with other disposable things
} // At this point in the code, only the SqlConnection gets disposed.

using块是try...finally的语法糖-因此先前的代码实际上已翻译为:

var  conn = new SqlConnection(connectionString);
try
{
    // Do all sort of stuff here with other disposable things
}
finally
{
    // At this point in the code, only the SqlConnection gets disposed.
    ((IDisposable)conn).Dispose();
}

答案 3 :(得分:0)

否,没有必要使用using内部使用。

这是一个包装器,因此我们不必显式处理对象。