【问题标题】:Using statement on object passed via parameter对通过参数传递的对象使用语句
【发布时间】:2021-07-30 01:46:00
【问题描述】:

寻求正确使用 C# using 语句的最佳输入。我可以在参数对象上使用using 语句,如以下不常见的示例代码 sn-p(即,多层应用程序)吗?

虽然sn-p的代码和我觉得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();
    }
}

请帮忙。

谢谢

【问题讨论】:

    标签: c#


    【解决方案1】:

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

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

    【讨论】:

    • 通常。并非总是如此 - 例如 Bitmap.FromStream 期望调用者 not 之后关闭它......它实际上取得了所有权。
    • 是的。相应更新。这是一个不寻常的例子。
    【解决方案2】:

    传递 IDisposable 实例的调用者应该是使用 using 语句的调用者。如果被调用者使用它,则对象将在“拥有”该对象的调用者的直接控制之外被释放。

    【讨论】:

      【解决方案3】:

      我可以在参数对象上使用 using 语句,如以下不常见的示例代码 sn-p(即,多层应用程序)吗?

      你可以,但这样做通常很奇怪。通常,创建StreamReader 的任何东西都会期望“拥有”它并在完成后处理它。您的ProcessFileAndReturnNumberFromStream 方法更常见:

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

      (虽然我个人会使用File.OpenText 而不是显式构造StreamReader。)

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

      您正在创建 Data 的新实例然后什么都不做,这也很奇怪 - 因为您的 GetNumberFromStream 方法不使用实例变量或覆盖基类方法,您应该考虑制作它静态的。

      【讨论】:

        【解决方案4】:

        这样的 API 会非常麻烦。

        你永远不会知道传递给方法的对象是否在方法内部。因此,如果这是您创建对象并将其传递到那里,您也永远不会知道是否应该处置刚刚创建并传递给方法的对象。

        我想,虽然这在技术上是可行的,但它会促进糟糕的编程风格。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-23
          • 2017-03-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多