简体   繁体   English

使用C#扩展方法显示意图

[英]The use of C# extension methods to show intention

Say I have a class, A , which holds some state: 假设我有一个类A ,它具有一些状态:

class A 
{
   // Ctor etc.

   string Foo { get; private set; }
   string Bar { get; private set; }
}

This class is used thoughout my codebase to hold application state. 整个我的代码库都使用该类来保存应用程序状态。 Ultimately, this state gets written into an XML file to save it. 最终,此状态被写入XML文件以进行保存。 Naturally, I'll write a method to do just that: 自然,我将写一个方法来做到这一点:

class A 
{
    // Ctor, the state, etc.

    public string ToXml()
    {
        // Writer implementation goes here
        return xmlString;
    }
}

ToXml does not require access to any of A 's private/protected instance variables, it only uses uses A 's public interface. ToXml不需要访问A的任何私有/受保护实例变量,它仅使用使用A的公共接口。 Since that's the case, I can implement ToXml as an extension method: 既然是这样,我可以将ToXml实现为扩展方法:

class A
{
    // Ctor, the state, etc.

    public static string ToXml(this A instance)
    {
        // Same deal as above
        return xmlString;
    }
}

An extension method can only use the outer interface of the class it is extending. 扩展方法只能使用它正在扩展的类的外部接口。 So, ignoring extension methods' main uses (extending a locked class, semantic helpers), what's the SO community's opinion on using an extension method for the sole purpose of communicating that a method only uses the outer interface of a class? 因此,忽略扩展方法的主要用途(扩展锁定的类,语义帮助程序),SO社区对使用扩展方法的唯一目的是传达一种方法仅使用类的外部接口的看法?

I ask this because I personally use extension methods alot --perhaps because I enjoy functional programming--but my coworkers dislike the rationale that I do so because I want to communicate that "this particular method definitely only uses the public interface of the class". 我之所以这样问,是因为我个人大量使用扩展方法(也许是因为我喜欢函数式编程),但是我的同事却不喜欢这样做的理由,因为我想传达“这种特定方法肯定只使用了类的公共接口”。 。

Note : These extension methods will appear as a substitute for their instance equivalents. 注意 :这些扩展方法将代替它们的实例等效项。 Because of that, there will not be any of the usual namespace issues that occur with extension methods. 因此,扩展方法不会出现任何常见的名称空间问题。 This question focuses entirely on the "communicate intent" aspect. 这个问题完全集中在“沟通意图”方面。

Extension methods are an example of the Open/Closed Principle . 扩展方法是“ 开放/封闭原则”的一个示例。 That is, it's open for extension, but closed for modification. 也就是说,它可以扩展,但是可以修改。

The major benefit of using Extension methods is that you do not have to recompile the class that is being extended, and thus force dependent code to be recompiled. 使用扩展方法的主要好处是您不必重新编译正在扩展的类,因此不必重新编译依赖的代码。 Also, by not changing the interface, you don't have to worry about any code depending on it breaking. 同样,通过不更改接口,您不必担心任何代码都取决于它的破坏情况。

If you're serious about SOLID principles, then this is a valid argument. 如果您认真对待SOLID原则,那么这是一个有效的论点。 Most developers don't see what the fuss is about. 大多数开发人员都不知道大惊小怪。

You have a class, A , that has a specific responsibility: holding a set of immutable data. 您有一个类A ,它具有特定的职责:保存一组不可变的数据。 If you now add a new method, ToXml , your class no longer has a specific responsibility; 如果现在添加新方法ToXml ,则您的类不再具有特定的职责; it has two loosely related responsibilities: holding data and translating that data into another form. 它有两个松散相关的职责:保存数据并将该数据转换为另一种形式。

So to preserve the single responsibility principle, such lossely related functionality should exist in another class, eg DataTransformationsOnA . 因此,为了保留单一职责原则,此类与损失相关的功能应存在于另一个类中,例如DataTransformationsOnA As the method is a pure function (it creates a deterministic output from an input with no side affects, it should be made a static method. Therefore, it follows that it can be made an extension method: 由于该方法是纯函数(它会从输入中创建确定的输出而没有任何副作用,因此应将其设为静态方法。因此,可以将其设为扩展方法:

static class DataTransformationsOnA
{
    public static string ToXml(this A instance)
    {
        // generate xmlSTring from instance
        return xmlString;
    }

    // other transformation methods can also be placed in this class
}

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

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