C# conditional using block statement

2020-05-20 07:19发布

I have the follow code but it is awkward. How could I better structure it? Do I have to make my consuming class implement IDisposable and conditionally construct the network access class and dispose it when I am done?

    protected void ValidateExportDirectoryExists()
    {
        if (useNetworkAccess)
        {
            using (new Core.NetworkAccess(username, password, domain))
            {
                CheckExportDirectoryExists();
            }
        }
        else
        {
            CheckExportDirectoryExists();
        }
    }

10条回答
三岁会撩人
2楼-- · 2020-05-20 07:57

By having your class implement IDisposable, the dispose method is called only when using the "using" statement. Otherwise you have to explicitly call dispose.

Typically IDisposable is implemented by objects that manage memory consumption outside of the garbage collector (like using unmanaged code for example). It provides a way to clean up any consumed memory.

So long as your NetworkAccess class implements IDisposable, the dispose method will get called as soon as the scope of the using statement is complete. If it is managed code, then no need to dispose of it. Just let the garbage collector do its work.

查看更多
一夜七次
3楼-- · 2020-05-20 08:02

I guess that is really a matter of cosmetics if the code is as simple as that.

I can envision how it could look the other way, and my vote will be for this version you have now.

查看更多
地球回转人心会变
4楼-- · 2020-05-20 08:04

Use your own try/finally block, which performs similar logic to the 'using', but only does the dispose if useNetworkAccess is set. Note that if useNetworkAccess could be affected by other threads, you should copy its value and use that copy both for creating the resource and disposing it.

查看更多
我欲成王,谁敢阻挡
5楼-- · 2020-05-20 08:08

One option, which is somewhat nasty but would work, based on the fact that the C# compiler calls Dispose only if the resource is non-null:

protected void ValidateExportDirectoryExists()
{
    using (useNetworkAccess 
               ? new Core.NetworkAccess(username, password, domain)
               : null)
    {
        CheckExportDirectoryExists();
    }
}

Another alternative would be to write a static method which returned either null or a NetworkAccess:

private Core.NetworkAccess CreateNetworkAccessIfNecessary()
{
    return useNetworkAccess
        ? new Core.NetworkAccess(username, password, domain)) : null;
}

Then:

protected void ValidateExportDirectoryExists()
{
    using (CreateNetworkAccessIfNecessary())
    {
        CheckExportDirectoryExists();
    }
}

Again, I'm still not sure I don't prefer the original... it really depends on how often you need this pattern.

查看更多
登录 后发表回答