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

The use of C# extension methods to show intention

假设我有一个 class、A,其中包含一些状态:

class A 
{
   // Ctor etc.

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

这个 class 在我的代码库中用于保存应用程序状态。最终,这个状态被写入一个 XML 文件以保存它。当然,我会写一个方法来做到这一点:

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

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

ToXml 不需要访问任何 A 的 private/protected 实例变量,它只使用 A 的 public 接口。既然如此,我可以将ToXml实现为扩展方法:

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

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

扩展方法只能使用它正在扩展的 class 的外部接口。因此,忽略扩展方法的主要用途(扩展锁定的 class、语义助手),SO 社区对使用扩展方法的唯一目的是传达一种方法仅使用 [= 的外部接口的看法是什么? 39=]?

我问这个是因为我个人使用扩展方法很多——也许是因为我喜欢函数式编程——但我的同事不喜欢我这样做的理由,因为我想交流"this particular method definitely only uses the public interface of the class".

注意:这些扩展方法将替代它们的实例等价物。因此,扩展方法不会出现任何常见的名称空间问题。这个问题完全集中在 "communicate intent" 方面。

扩展方法是Open/Closed Principle的一个例子。即对扩展开放,对修改关闭。

使用扩展方法的主要好处是您不必重新编译正在扩展的 class,从而强制重新编译相关代码。此外,通过不更改界面,您不必担心任何依赖于它的代码会被破坏。

如果您认真对待 SOLID 原则,那么这是一个有效的论点。大多数开发人员不明白有什么大惊小怪的。

你有一个 class、A,它有一个特定的职责:保存一组不可变的数据。如果你现在添加一个新方法,ToXml,你的class不再有特定的责任;它有两个松散相关的职责:保存数据并将该数据转换为另一种形式。

因此,为了保持单一职责原则,这种不相关的功能应该存在于另一个class,例如DataTransformationsOnA。由于该方法是纯函数(它从输入创建确定性输出而没有副作用,因此应该将其设为静态方法。因此,可以将其设为扩展方法:

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
}