【问题标题】:Should I separate Dispose logic into a partial class file?我应该将 Dispose 逻辑分离到部分类文件中吗?
【发布时间】:2010-10-06 18:02:55
【问题描述】:

在重构一些 C# 类时,我遇到了实现 IDisposable 的类。

不假思索,我为每个实现 IDisposable 接口的类创建了部分类文件。

例如)对于 Stamper.cs -> Stamper.cs + Stamper.Dispose.cs 其中 Stamper.cs 包含用于标记的实际逻辑 和 Stamper.Dispose.cs 包含处置逻辑

// Stamper.cs
public partial class Stamper
{
// actual logic
}

// Stamper.Dispose.cs
public partial class Stamper: IDisposable
{
// Implement IDisposable
}

当我查看代码时,Stamper.cs 现在看起来更加简洁易读(现在大约 52 行而不是 100 行,大约 50 行只是一个清理处置代码)

我是不是太过分了?

*编辑:感谢大家的意见 - 我决定将两个文件合二为一。 我遇到的问题是我实际上在更新实际逻辑后忘记更新 IDisposable 实现。

此外,在源代码中的方法之间导航没有太大问题。 在我的具体情况下,第一个原因似乎足以让我坚持使用一个文件解决方案。

【问题讨论】:

  • 请添加“主观”标签。 ;)

标签: c# refactoring idisposable partial-classes


【解决方案1】:

是的,太远了。只是在代码周围贴上#Region 并将其折叠以使您看不到它有什么问题?

【讨论】:

    【解决方案2】:

    这似乎与为构造函数逻辑创建部分类一样任意。现在我必须查看两个文件来了解该类。部分课程只对设计师的东西才真正值得......

    【讨论】:

    • 让设计器或代码生成工具来处理部分类似乎是正确的。围绕源导航没有问题。我的部分类实现的缺点是我实际上忘记更新 IDisopsable impl。更改实际逻辑后有用链接:tinyurl.com/abmypf
    【解决方案3】:

    我希望在同一个文件中看到处置逻辑,作为保证实现 IDisposable 的资源。虽然存在主观因素,但我认为这太过分了

    【讨论】:

      【解决方案4】:

      我认为您的解决方案不合理。部分类通常应该只用于将开发人员代码与生成器代码分开。区域通常可以更好地为您的代码添加结构。

      【讨论】:

      • 对不起,JohannesH,我不认为添加区域通常对任何事情都有好处。我认为区域很烦人,因为我通常看不到完整的源代码
      • 好吧...好吧,实际上我认为您应该按照自己喜欢的方式进行...只要您将其作为一致的团队实践。我不会那样做的。然而,归根结底,每天都必须与它一起工作的是你。因此,如果您认为这样更好,那就去吧。 :)
      【解决方案5】:

      如果您的清理程序繁重,这是可以接受的,但并不理想。

      这对于样板文件可能是一个好习惯,例如暴露的事件、繁重的序列化方法以及在您的情况下的内存管理。

      更喜欢部分类而不是轮廓(#region)。如果您必须使用部分类或代码大纲来使代码可读,这通常表明代码需要更改。如果代码对于维护该类是绝对必要的,则仅作为最后的手段使用部分类(或区域)。

      在您的情况下,您可以使用一个简单地包装非托管资源并公开单个 Dispose 的类。然后在你的另一个类中,使用托管对象并在没有逻辑的情况下处理它。

      如果您的类只是一个简单的包装,那么我会说您的方法是矫枉过正,因为该类的全部目的是处置非托管资源。

      【讨论】:

      • 请解释区域是个问题但部分类不是问题的原因?无论哪种方式,课程都非常繁琐,需要一些额外的组织。将其拆分为多个文件而不是单个文件中的区域让我更喜欢品味。
      • 区域取决于您的 IDE 的配置方式,而文件则不是。例如,我喜欢使用 Consolas,它使区域图标几乎不可见且无法单击。此外,将内容放在不同的文件中会使“隐藏”代码显而易见,而区域很容易错过。
      • 我使用 Consolas 9pt,并且区域折叠/展开图标几乎不可见,也没有难以点击的问题。区域可能很容易被忽略,但至少它们就在那里——更容易扫描单个文件并查看所有实现细节,而不是读取 2 个文件才能看到整个画面。
      • 更改了我的答案,使其更加明显,这是一种观点,而不是事实。此外,更明显的是,使用部分或区域不是最佳解决方案,而是解决潜在问题的最后手段。
      【解决方案6】:

      有点奇怪的问题,因为它只对开发者有影响,完全取决于个人喜好。我只能告诉你我更喜欢什么,那就是如果 dispose 部分中有大量逻辑,我会这样做。

      【讨论】:

        【解决方案7】:

        就我个人而言,我尽量让我的实例化/初始化逻辑和我的清理/处置逻辑并排,这是一个很好的提醒。

        对于部分类,我唯一​​使用它们的情况是类非常大并且可以分类为方法组。隐藏设计器代码也很棒。

        【讨论】:

          【解决方案8】:

          当且仅当相关代码由计算机生成时,我更倾向于使用部分类。如果您有许多共享相似代码的类(由于各种原因必须重复,而不是被拉到自己的类中),那么拥有一些模板和一个基于此类模板生成代码的程序可能会很有用。在这种情况下,模板将被视为源文件,然后生成文件作为中间对象代码。将模板生成的代码提取到部分类中似乎是完全合适的。

          在 vb.net 中,这种方法可能会很好地允许在 IDisposable 对象中安全地一起处理字段声明、初始化和清理。需要适量的样板代码,但之后的字段声明非常干净。例如:

          ' 假设选项隐含在: Dim MyThingie = RegDisposable(新 DisposableThingie) ' 如果未启用隐式: 将 MyThingie 调暗为 DisposableThingie = RegDisposable(New DisposableThingie)

          RegDisposable 将是一个类成员,它将新的 DisposableThingie 添加到该类持有的列表中。然后该类的 Dispose 例程将 Dispose 列表中的所有项目。

          不幸的是,在 C# 中没有干净的方法可以做任何类似的事情,因为字段初始化器无法使用即将构造的对象(在 vb.net 中,字段初始化器在构造基础对象之后运行)。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-11-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-10-03
            相关资源
            最近更新 更多