user1660166
user1660166

Reputation: 79

Using statement on object passed via parameter

Seeking best inputs on correct usage of C# using statement. Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?

Although the code snippet is different from what I feel that the using statement should be in ProcessFileAndReturnNumberFromStream() method of 'Business' class.

Why is it an uncommon practice to use using statement on object passed via parameter? Please correct or elaborate on the flaw?

using System;
using System.IO;

class Data
{
    public double? GetNumberFromStream(StreamReader sr)
    {
        double? number;
        try
        {
            using (sr)
            {
                number = Convert.ToDouble(sr.ReadToEnd());
                return number;
            }
        }
        finally
        {
            number = null;
        }
    }
}

class Business
{
    public double? ProcessFileAndReturnNumberFromStream()
    {
        string fileName = "Test.txt";
        StreamReader sr = new StreamReader(fileName);
        Data dat = new Data();
        return dat.GetNumberFromStream(sr);  
     }
}

class GUI
{
    static void Main()
    {
        Business bus = new Business();
        double? number = bus.ProcessFileAndReturnNumberFromStream();

        Console.WriteLine(number);
        Console.ReadKey();
    }
}

Please help.

Thanks

Upvotes: 1

Views: 2189

Answers (4)

Wiktor Zychla
Wiktor Zychla

Reputation: 48250

Such API would be extremely troublesome.

You would never know whether or not the object passed to a method is disposed inside the method or not. Thus, if this is you who create the object and pass it there, you would also never know whether or not you should dispose the object you have just created and passed to the method or not.

I guess then, while this is technically possible, it would promote the bad programming style.

Upvotes: 0

slugster
slugster

Reputation: 49984

The caller that is passing the instance of IDisposable should be the one to use the using statement. If the callee uses it, the object will be disposed while outside the immediate control of the caller who 'owns' the object.

Upvotes: 2

Mitch Wheat
Mitch Wheat

Reputation: 300589

If a method is passed an object that implements IDisposable, it's usually the responsibility of the caller to manage the lifetime of that object, rather than the callee.

public double? ProcessFileAndReturnNumberFromStream()
{
    string fileName = "Test.txt";
    Data dat = new Data();

    using (StreamReader sr = new StreamReader(fileName))
    {
        return dat.GetNumberFromStream(sr);  
    }
 }

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1501033

Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?

You can, but it's generally odd to do so. Usually whatever is creating the StreamReader would be expecting to "own" it and dispose of it when they're done with it. It would be more usual for your ProcessFileAndReturnNumberFromStream method to be:

using (StreamReader sr = new StreamReader(fileName))
{
    Data dat = new Data();
    return dat.GetNumberFromStream(sr);
}

(Although I'd personally use File.OpenText instead of explicitly constructing the StreamReader.)

Your GetNumberFromStream method would then not need the using statement. It also doesn't need the try/finally block at all - it's an odd implementation all round, given that it will never return null, either...

It's also odd that you're creating a new instance of Data and then doing nothing with it - as your GetNumberFromStream method doesn't use an instance variables or override a base class method, you should consider making it static.

Upvotes: 1

Related Questions