return the variable used for using inside the usin

2019-04-05 16:42发布

I am returning the variable I am creating in a using statement inside the using statement (sounds funny):

public DataTable foo ()
{
    using (DataTable properties = new DataTable())
    {
       // do something
       return properties;
    }
}

Will this Dispose the properties variable??

After doing this am still getting this Warning:

Warning 34 CA2000 : Microsoft.Reliability : In method 'test.test', call System.IDisposable.Dispose on object 'properties' before all references to it are out of scope.

Any Ideas?

Thanks

7条回答
太酷不给撩
2楼-- · 2019-04-05 17:03

Supposedly, this is the pattern for a factory method that creates a disposable object. But, I've still seen Code Analysis complain about this, too:

        Wrapper tempWrapper = null;
        Wrapper wrapper = null;

        try
        {
            tempWrapper = new Wrapper(callback);
            Initialize(tempWrapper);

            wrapper = tempWrapper;
            tempWrapper = null;
        }
        finally
        {
            if (tempWrapper != null)
                tempWrapper.Dispose();
        }

        return wrapper;

This should guarantee that if the initialization fails, the object is properly disposed, but if everything succeeds, an undisposed instance is returned from the method.

MSDN Article: CA2000: Dispose objects before losing scope.

查看更多
劫难
3楼-- · 2019-04-05 17:05

Your code using the using keyword expands to:

{
    DataTable properties = new DataTable();
    try
    {
        //do something
        return properties;
    }
    finally
    {
        if(properties != null)
        {
            ((IDisposable)properties).Dispose();
        }
    }
}

Your variable is being disposed by nature of how using works. If you want to be able to return properties, don't wrap it in a using block.

查看更多
放我归山
4楼-- · 2019-04-05 17:15

The other responses are correct: as soon as you exit the using block, your object is disposed. The using block is great for making sure that an object gets disposed in a timely manner, so if you don't want to rely on the consumers of your function to remember to dispose the object later, you can try something like this:

public void UsingDataContext (Action<DataContext> action)
{
    using (DataContext ctx = new DataContext())
    {
       action(ctx)
    }
}

This way you can say something like:

var user = GetNewUserInfo();
UsingDataContext(c => c.UserSet.Add(user));
查看更多
小情绪 Triste *
5楼-- · 2019-04-05 17:21

Yes. Why are you using the using keyword on something you don't want disposed at the end of the code block?

The purpose of the using keyword is to dispose of the object.

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

查看更多
迷人小祖宗
6楼-- · 2019-04-05 17:24

If you want to return it, you can't wrap it in a using statement, because once you leave the braces, it goes out of scope and gets disposed.

You will have to instantiate it like this:

public DataTable Foo() 
{ 
    DataTable properties = new DataTable();
    return properties; 
} 

and call Dispose() on it later.

查看更多
Root(大扎)
7楼-- · 2019-04-05 17:26

The point of a using block is to create an artificial scope for a value/object. When the using block completes, the object is cleaned up because it is no longer needed. If you really want to return the object you are creating, than it is not a case where you want to use using.

This will work just fine.

public DataTable foo ()
{
    DataTable properties = new DataTable();
    // do something
    return properties;
}
查看更多
登录 后发表回答