简体   繁体   中英

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

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

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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM