【问题标题】:How are partial methods used in C# 3.0?C# 3.0 中如何使用部分方法?
【发布时间】:2008-09-03 17:42:41
【问题描述】:

我在最新的C# language specification 中阅读了有关部分方法的内容,因此我了解其中的原理,但我想知道人们实际上是如何使用它们的。是否有特定的设计模式可以从部分方法中受益?

【问题讨论】:

    标签: c# design-patterns .net-3.5 partial-methods


    【解决方案1】:

    部分方法被引入的原因与 .Net 2 中部分类的原因相似。

    分部类是一种可以跨多个文件拆分的类 - 编译器在运行时将它们全部构建到一个文件中。

    这样做的好处是 Visual Studio 可以为类的一部分提供图形设计器,而编码人员则在其他部分工作。

    最常见的例子是表单设计器。开发者不希望大部分时间都是手动定位按钮、输入框等。

    • 在 .Net 1 中,它是在 #region 块中自动生成的代码
    • 在 .Net 2 中,这些成为单独的设计器类 - 表单仍然是一个类,它只是分成一个由开发人员编辑的文件和一个由表单设计器编辑的文件

    这使得维护两者变得更加容易。合并更简单,VS 表单设计器意外撤消编码人员手动更改的风险更小。

    在 .Net 3.5 中引入了 Linq。 Linq 有一个 DBML 设计器,用于构建您的数据结构并生成自动代码。

    这里额外的一点是代码需要提供开发人员可能想要填写的方法。

    由于开发人员将扩展这些类(带有额外的部分文件),因此他们不能在这里使用抽象方法。

    另一个问题是这些方法大部分时间都不会被调用,调用空方法是浪费时间。

    空方法are not optimised out.

    所以 Linq 会生成空的部分方法。如果您不创建自己的部分来完成它们,C# 编译器只会优化它们。

    因此它可以做到这一点,部分方法总是返回 void。

    如果您创建一个新的 Linq DBML 文件,它将自动生成一个部分类,类似于

    [System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDB")]
    public partial class MyDataContext : System.Data.Linq.DataContext
    {
        ...
    
        partial void OnCreated();
        partial void InsertMyTable(MyTable instance);
        partial void UpdateMyTable(MyTable instance);
        partial void DeleteMyTable(MyTable instance);
    
        ...
    

    然后在你自己的部分文件中你可以扩展它:

    public partial class MyDataContext
    {
        partial void OnCreated() {
            //do something on data context creation
        }
    }
    

    如果您不扩展这些方法,它们会立即得到优化。

    部分方法不能公开 - 因为它们必须在那里才能让其他类调用。如果您编写自己的代码生成器,我可以看到它们很有用,但除此之外,它们仅对 VS 设计器真正有用。

    我之前提到的例子是一种可能性:

    //this code will get optimised out if no body is implemented
    partial void DoSomethingIfCompFlag();
    
    #if COMPILER_FLAG
    //this code won't exist if the flag is off
    partial void DoSomethingIfCompFlag() {
        //your code
    }
    #endif
    

    另一个潜在用途是,如果您有一个大型而复杂的类溢出到多个文件中,您可能希望在调用文件中进行部分引用。但是我认为在这种情况下,您应该首先考虑简化类。

    【讨论】:

    • 很好的答案;为了增加一点点价值,部分类也可用于向自动生成的 Web 服务类添加方法和功能。
    • @Keith"部分方法不能公开 - 因为它们必须在那里才能让其他类调用" 我认为这个限制是无效的,例如在我的项目中,我在一个类中有大约 15 个方法,为了更好的可读性,我想将它们保留在部分类中。但由于我无法将它们公开,我不得不将它们保留在同一个类中。
    【解决方案2】:

    部分方法在概念上与 GoF Template Method 行为模式(Design Patterns,p325)非常相似。

    它们允许在一个地方定义算法或操作的行为,并在其他地方实现或更改,从而实现可扩展性和定制化。我已经开始在 C# 3.0 中使用部分方法而不是模板方法,因为我认为代码更简洁。

    一个不错的特性是未实现的部分方法在编译时不会产生运行时开销。

    【讨论】:

    • 是的,真的!多么了不起的事情——一个人(你)看到了一些东西,而另一个人(我)看不到
    【解决方案3】:

    Code generation是它们存在的主要原因之一,也是使用它们的主要原因之一。


    编辑:尽管该链接指向特定于 Visual Basic 的信息,但相同的基本原则与 C# 相关。

    【讨论】:

      【解决方案4】:

      我将它们视为轻量级事件。您可以拥有一个可重用的代码文件(通常是自动生成的,但不一定),并且对于每个实现,只需处理您在部分类中关心的事件。事实上,这就是它在 LINQ to SQL 中的使用方式(以及发明语言功能的原因)。

      【讨论】:

        【解决方案5】:

        这里是 C#.NET 3.0 中部分类的最佳资源:http://msdn.microsoft.com/en-us/library/wa80x488(VS.85).aspx

        我尽量避免使用分部类(Visual Studio 为设计器文件创建的分部除外;这些都很棒)。对我来说,将一个类的所有代码放在一个地方更为重要。如果您的类设计良好并代表一件事 (single responsibility principle),那么该一件事的所有代码都应该放在一个地方。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-28
          • 2015-12-19
          • 2019-03-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多