简体   繁体   English

部分类与扩展方法

[英]Partial Class vs Extension Method

I dont have much experience of using these 2 ways to extend a class or create extension methods against a class.我没有太多使用这 2 种方法来扩展类或针对类创建扩展方法的经验。 By looking others work, I have a question here.通过查看其他人的工作,我在这里有一个问题。

I saw people using a partial class to extend an entity class in a project.我看到人们使用分部类来扩展项目中的实体类。 Meanwhile, in the same project, there is another folder containing a lot extension methods to the entity class.同时,在同一个项目中,还有一个文件夹包含了很多实体类的扩展方法。

Is it right to do so?这样做是否正确? I mean these 2 ways both work well.我的意思是这两种方式都很好用。 Could you give me some real idea of how to pick one or the other when I want extend a class?当我想扩展一个类时,你能给我一些关于如何选择一个或另一个的真实想法吗?

Some of differences that will determine whether you want to use a Partial Class or an Extension Method are将决定您是要使用分部类还是扩展方法的一些差异是

Partial Class部分类

  • Only works against classes in the same project/assembly仅适用于同一项目/程序集中的类
  • Target class has to be marked as partial目标类必须标记为部分
  • Has access to the Target class' fields and protected members可以访问 Target 类的字段和受保护的成员
  • Target must be a class implementation目标必须是类实现

Extension Method扩展方法

  • Can be applied against classes in other assembles可以应用于其他汇编中的类
  • Must be static, has access to only the Target classes public members必须是静态的,只能访问 Target 类的公共成员
  • Target of extension can be a concrete type, or an abstract type or interface扩展的目标可以是具体类型,也可以是抽象类型或接口

Partial classes should be used in code generation scenarios.在代码生成场景中应该使用部分类。

Since the generated file might get overwritten at any time, one uses partial classes to write into the non-generated file.由于生成的文件随时可能被覆盖,因此可以使用部分类来写入非生成的文件。

Additionally, partials will only work if they are part of the same assembly - they cannot cross assembly boundaries.此外,partials 仅在它们是同一程序集的一部分时才有效——它们不能跨越程序集边界。

If these are not your constraints, you can and should use extension methods - of course, after considering other possibilities such as inheritance and composition for suitability.如果这些不是你的约束,你可以而且应该使用扩展方法——当然,在考虑其他可能性之后,比如继承和组合的适用性。

You can use extension methods on a NULL instance but not instance methods (of partial classes or otherwise).您可以在 NULL 实例上使用扩展方法,但不能在实例方法(部分类或其他)上使用。 This is a consequence of extension methods actually being static.这是扩展方法实际上是静态的结果。

Partial works only if both files are in the same project, and you can access private and protected members of that class.只有当两个文件都在同一个项目中并且您可以访问该类的私有成员和受保护成员时,部分才有效。

Extension methods are just static methods, and can't access private members.扩展方法只是静态方法,不能访问私有成员。

So if you want to access private and protected members, only way you have is partial, if no, answer to the question, should the method you want to add be visible everywhere you want to use class?因此,如果您想访问私有成员和受保护成员,那么您拥有的唯一方法是部分,如果不是,请回答这个问题,您要添加的方法是否应该在您想使用类的任何地方都可见? if yes, use partial, if no, it's some kind of extension, use extension methods.如果是,使用部分,如果不是,它是某种扩展,使用扩展方法。

By the way, if the first class is not generated by some tool, you can write your function there except of using partial ;)顺便说一句,如果第一个类不是由某个工具生成的,您可以在那里编写函数,除了使用 partial ;)

hope this helps希望这可以帮助

I use partial methods when I need a class to implement an interface, but the class code is autogenerated (VS uses partial classes to generate code for both web services and EF models).当我需要一个类来实现接口时,我使用部分方法,但类代码是自动生成的(VS 使用部分类为 Web 服务和 EF 模型生成代码)。

I use extension methods when the new method that I'm adding to the type is appropriate for any value of that type.当我添加到类型的新方法适用于该类型的任何值时,我使用扩展方法。 (good examples: int.IsEven(), string.IsEmpty(); bad examples: int.IsOldEnoughToDrive(), string.IsLastName()). (好的例子:int.IsEven()、string.IsEmpty();坏的例子:int.IsOldEnoughToDrive()、string.IsLastName())。

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

If you choose the Partial Class route but find you are repeating the same code, switch to Extension Methods.如果您选择 Partial Class 路线,但发现重复了相同的代码,请切换到 Extension Methods。

For example, i have many generated classes with methods which return IEnumerable<Track> data.例如,我有许多生成的类,其方法返回IEnumerable<Track>数据。 I want to extend each class somehow to give me the option of receiving the data in the format IEnumerable<MediaItem> .我想以某种方式扩展每个类,以便我可以选择以IEnumerable<MediaItem>格式接收数据。

I have a general requirement here to transform IEnumerable<Track> data to IEnumerable<MediaItem> .我在这里有一个一般要求将IEnumerable<Track>数据转换为IEnumerable<MediaItem> In this case, rather than writing multiple partial class methods an extension method works best:在这种情况下,与编写多个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
               };
    }
}

This gives me the following options:这给了我以下选项:

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

A partial class is useful when you want to extend a generated class.当您想要扩展生成的类时,分部类很有用。 This way you can write your code in one file, and then when/if the other 'part' of your class needs to be re-generated, it can be done safely, as that code file hasn't changed.通过这种方式,您可以在一个文件中编写代码,然后当/如果需要重新生成类的另一“部分”时,可以安全地完成,因为该代码文件没有更改。

Partial Class - 

split the definition of a class or a struct, or an interface over two or more source files将类或结构或接口的定义拆分为两个或多个源文件

Extension Method  

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM