return the variable used for using inside the usin

2019-04-05 17:07发布

问题:

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

回答1:

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.



回答2:

Yes, it will dispose it - and then return it. This is almost always a bad thing to do.

In fact for DataTable, Dispose almost never does anything (the exception being if it's remoted somewhere, IIRC) but it's still a generally bad idea. Normally you should regard disposed objects as being unusable.



回答3:

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.



回答4:

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



回答5:

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;
}


回答6:

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.



回答7:

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));