C# 对通过参数传递的对象使用语句

C# 对通过参数传递的对象使用语句,c#,C#,寻找正确使用C#using语句的最佳输入。我是否可以在参数对象上使用using语句,如下面不常见的示例代码片段(即多层应用程序)中所示 虽然代码片段与我认为using语句应该位于'Business'类的ProcessFileAndReturnNumberFromStream()方法中的代码片段不同 为什么在通过参数传递的对象上使用using语句是一种不常见的做法?请更正或详细说明缺陷 using System; using System.IO; class Data { public

寻找正确使用C#using语句的最佳输入。我是否可以在参数对象上使用
using
语句,如下面不常见的示例代码片段(即多层应用程序)中所示

虽然代码片段与我认为using语句应该位于'Business'类的
ProcessFileAndReturnNumberFromStream()方法中的代码片段不同

为什么在通过参数传递的对象上使用using语句是一种不常见的做法?请更正或详细说明缺陷

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();
    }
}
请帮忙

谢谢

我是否可以在参数对象上使用using语句,如下面不常见的示例代码段(即多层应用程序)中所示

你可以,但这样做通常很奇怪。通常,创建
StreamReader
的任何人都希望“拥有”它,并在处理完后将其处理掉。您的
ProcessFileAndReturnNumberFromStream
方法通常是:

using (StreamReader sr = new StreamReader(fileName))
{
    Data dat = new Data();
    return dat.GetNumberFromStream(sr);
}
(尽管我个人会使用
File.OpenText
而不是显式构建
StreamReader

然后,您的
GetNumberFromStream
方法将不需要
using
语句。它也根本不需要
try/finally
块-这是一个奇怪的实现,因为它也不会返回null

<>也奇怪,你正在创建一个新的实例:<代码>数据< /代码>,然后不做任何事情——因为你的<代码> GETNUBLFROWSWORT 方法不使用实例变量或重写基类方法,你应该考虑使它静态化。 我是否可以在参数对象上使用using语句,如下面不常见的示例代码段(即多层应用程序)中所示

你可以,但这样做通常很奇怪。通常,创建
StreamReader
的任何人都希望“拥有”它,并在处理完后将其处理掉。您的
ProcessFileAndReturnNumberFromStream
方法通常是:

using (StreamReader sr = new StreamReader(fileName))
{
    Data dat = new Data();
    return dat.GetNumberFromStream(sr);
}
(尽管我个人会使用
File.OpenText
而不是显式构建
StreamReader

然后,您的
GetNumberFromStream
方法将不需要
using
语句。它也根本不需要
try/finally
块-这是一个奇怪的实现,因为它也不会返回null


也奇怪,你正在创建一个新的实例:<代码>数据< /代码>,然后不做任何事情——因为你的<代码> GETNoMyFraseStudio方法不使用实例变量或重写基类方法,你应该考虑使它静态。

< P>如果一个方法通过了一个实现了<代码> IDISPOSTABLE 的对象,管理对象的生命周期通常是调用方的责任,而不是被调用方的责任

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

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

如果向方法传递了一个实现了
IDisposable
的对象,则通常是调用方负责管理该对象的生存期,而不是被调用方

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

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

传递IDisposable实例的调用方应该是使用
using
语句的调用方。如果被调用方使用它,对象将在不受“拥有”对象的调用方直接控制的情况下被释放。

传递IDisposable实例的调用方应该是使用
using
语句的调用方。如果被调用方使用它,对象将在“拥有”对象的调用方无法直接控制的情况下被释放。

这样的API将非常麻烦

您永远不会知道传递给方法的对象是否在该方法中被释放。因此,如果创建对象并将其传递给该方法的是您,那么您也永远不会知道是否应该处理刚刚创建并传递给该方法的对象


我想,虽然这在技术上是可能的,但它会助长糟糕的编程风格。

这样的API会非常麻烦

您永远不会知道传递给方法的对象是否在该方法中被释放。因此,如果创建对象并将其传递给该方法的是您,那么您也永远不会知道是否应该处理刚刚创建并传递给该方法的对象


我想,虽然这在技术上是可能的,但它会助长糟糕的编程风格。

通常。不总是-例如
Bitmap.FromStream
希望调用方以后不要关闭它。。。事实上,这需要所有权。相应更新。这是一个不寻常的例子。不总是-例如
Bitmap.FromStream
希望调用方以后不要关闭它。。。事实上,这需要所有权。相应更新。这是一个不寻常的例子。