简体   繁体   中英

The use of C# extension methods to show intention

Say I have a class, A , which holds some state:

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. 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. Since that's the case, I can implement ToXml as an extension method:

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?

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. 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. If you now add a new method, ToXml , your class no longer has a specific responsibility; 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 . 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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