部分类与扩展方法

时间:2011-05-16 12:51:32

标签: c# extension-methods partial-classes

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

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

这样做是对的吗?我的意思是这两种方式都运作良好。当我想扩展一个课程时,你能给我一些真实的练习如何从中挑选一个吗?

9 个答案:

答案 0 :(得分:37)

确定是否要使用部分类或扩展方法的一些差异是

部分班级

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

扩展方法

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

答案 1 :(得分:24)

应在代码生成方案中使用部分类。

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

此外,partials只有在它们属于同一个程序集时才有效 - 它们不能跨越程序集边界。

如果这些不是你的约束,你可以而且应该使用扩展方法 - 当然,在考虑其他可能性之后,例如继承和组合的适用性。

答案 2 :(得分:3)

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

答案 3 :(得分:2)

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

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

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

顺便说一下,如果某个工具没有生成第一个类,除了使用partial之外,你可以在那里编写函数;)

希望这会有所帮助

答案 4 :(得分:2)

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

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

如果选择“部分类”路线但发现重复相同的代码,请切换到“扩展方法”。

例如,我有很多生成的类,其方法返回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..

答案 7 :(得分:0)

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

答案 8 :(得分:0)

Partial Class - 

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

Extension Method  

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