【问题标题】:Partial Class vs Extension Method部分类与扩展方法
【发布时间】:2011-05-16 12:51:31
【问题描述】:

我没有太多使用这两种方法来扩展类或针对类创建扩展方法的经验。通过查看其他人的工作,我在这里有一个问题。

我看到人们在项目中使用分部类来扩展实体类。同时,在同一个项目中,还有一个文件夹,里面有很多实体类的扩展方法。

这样做对吗?我的意思是这两种方式都运作良好。当我想扩展一个类时,你能给我一些关于如何选择一个或另一个的真正想法吗?

【问题讨论】:

  • @Cody Gray 你的意思是c#中的设计模式或语言特性
  • 这是一种设计模式。组合不是“C# 中的语言特性”,也不是我所知道的任何其他语言。
  • Cody Gray 的评论是一个纯粹的教条式断言,没有争论也不能争论。部分类/方法和扩展方法服务于不同的目的,并开启了完全不同的可能性。组合与它无关,它是第三个概念,有其优点/缺点。

标签: c# extension-methods partial-classes


【解决方案1】:

决定您是使用部分类还是扩展方法的一些差异是

部分类

  • 仅适用于同一项目/程序集中的类
  • 必须将目标类标记为部分
  • 可以访问目标类的字段和受保护的成员
  • 目标必须是类实现

扩展方法

  • 可以应用于其他程序集中的类
  • 必须是静态的,只能访问目标类的公共成员
  • 扩展的目标可以是具体类型,也可以是抽象类型或接口

【讨论】:

  • 另外:通过部分类引入的方法出现在智能感知中,但对于扩展方法,编码人员必须知道它。 VS 可以帮助您包含命名空间,但您仍然需要知道方法名称。不熟悉扩展方法的人可能不知道它们甚至存在。 (我经常难以记住自己的扩展方法,这就是为什么我考虑将一些转换为部分类)。
【解决方案2】:

在代码生成场景中应该使用部分类。

由于生成的文件随时可能被覆盖,因此使用部分类写入非生成的文件。

此外,partials 仅在它们是同一程序集的一部分时才有效 - 它们不能跨越程序集边界。

如果这些不是您的限制条件,您可以并且应该使用扩展方法 - 当然,在考虑其他可能性(例如继承和组合的适用性)之后。

【讨论】:

  • 非常适合数据库优先的 ADO.net 数据模型。
【解决方案3】:

您可以在 NULL 实例上使用扩展方法,但不能使用实例方法(部分类或其他)。这是扩展方法实际上是静态的结果。

【讨论】:

    【解决方案4】:

    当我需要一个类来实现接口时,我使用分部方法,但类代码是自动生成的(VS 使用分部类来为 Web 服务和 EF 模型生成代码)。

    当我添加到该类型的新方法适用于该类型的 any 值时,我会使用扩展方法。 (好例子:int.IsEven()、string.IsEmpty();坏例子:int.IsOldEnoughToDrive()、string.IsLastName())。

    【讨论】:

    • 好的扩展方法与业务逻辑无关,不是吗?
    • 通常情况下,是的。通过遵守扩展方法与给定类型的任何值相关的规则,您可以过滤掉大部分在扩展方法中包含业务逻辑的机会。
    【解决方案5】:

    您可以在您正在开发的项目中使用部分类,而扩展方法也可以用于扩展您也没有源代码的项目..

    【讨论】:

      【解决方案6】:

      仅当两个文件都在同一个项目中时,部分才有效,并且您可以访问该类的私有成员和受保护成员。

      扩展方法只是静态方法,不能访问私有成员。

      因此,如果您想访问私有成员和受保护成员,则只有部分方法,如果否,请回答问题,您要添加的方法是否应该在您想使用类的任何地方都可见?如果是,使用部分,如果不是,它是某种扩展,使用扩展方法。

      顺便说一句,如果第一个类不是由某个工具生成的,你可以在那里编写你的函数,除了使用部分;)

      希望对你有帮助

      【讨论】:

        【解决方案7】:

        如果您选择 Partial Class 路线但发现您重复相同的代码,请切换到扩展方法。

        例如,我有许多带有返回IEnumerable<Track> 数据的方法的生成类。我想以某种方式扩展每个类,让我可以选择以IEnumerable<MediaItem> 格式接收数据。

        我在这里有一个一般要求,将IEnumerable<Track> 数据转换为IEnumerable<MediaItem>。在这种情况下,与其编写多个 partial class 方法,不如使用扩展方法:

        public static class ExtensionMethods
        {
            public static IEnumerable<MediaItem> ToMediaItems(this IEnumerable<Track> tracks)
            {
                return from t in tracks
                       select new MediaItem
                       {
                           artist = t.Artist,
                           title = t.Title,
                           // blah blah
                       };
            }
        }
        

        这给了我以下选项:

        var data = Playlist.Tracks.ToMediaItems();
        var data = Podcast.Tracks.ToMediaItems();
        // etc..
        

        【讨论】:

          【解决方案8】:

          当您想要扩展生成的类时,部分类很有用。这样,您可以将代码编写在一个文件中,然后当/如果需要重新生成类的其他“部分”时,可以安全地完成,因为该代码文件没有更改。

          【讨论】:

          • 但是这个论点也适用于扩展方法
          【解决方案9】:
          Partial Class - 
          

          将类或结构或接口的定义拆分为两个或多个源文件

          Extension Method  
          

          扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型

          【讨论】:

            猜你喜欢
            • 2010-10-27
            • 1970-01-01
            • 2021-12-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-28
            • 2012-01-29
            • 2012-07-05
            相关资源
            最近更新 更多