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

本文关键字:显示 示意图 方法 扩展 使用 | 更新日期: 2023-09-27 18:27:21

假设我有一个类A,它保持某种状态:

class A 
{
   // Ctor etc.
   string Foo { get; private set; }
   string Bar { get; private set; }
}

这个类是在我的整个代码库中用来保存应用程序状态的。最终,这个状态会被写入一个XML文件来保存它

class A 
{
    // Ctor, the state, etc.
    public string ToXml()
    {
        // Writer implementation goes here
        return xmlString;
    }
}

ToXml不需要访问A的任何私有/受保护的实例变量,它只使用A的公共接口。既然是这样,我就可以将ToXml实现为一种扩展方法:

class A
{
    // Ctor, the state, etc.
    public static string ToXml(this A instance)
    {
        // Same deal as above
        return xmlString;
    }
}

扩展方法只能使用它正在扩展的类的外部接口。那么,忽略扩展方法的主要用途(扩展锁定类、语义助手),So社区对使用扩展方法来传达方法只使用类的外部接口的唯一目的有何看法?

我之所以这么问,是因为我个人经常使用扩展方法——也许是因为我喜欢函数式编程——但我的同事不喜欢我这样做的理由,因为我想传达"这个特定的方法肯定只使用类的公共接口"。

注意:这些扩展方法将作为其实例等效方法的替代品出现。因此,扩展方法将不会出现任何常见的命名空间问题。这个问题完全集中在"沟通意图"方面。

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

Extension方法是开放/封闭原则的一个例子。也就是说,它对扩展是开放的,但对修改是关闭的。

使用Extension方法的主要好处是,您不必重新编译正在扩展的类,从而强制重新编译依赖代码。此外,通过不更改接口,您不必担心依赖它的任何代码会崩溃。

如果你认真对待SOLID原则,那么这是一个有效的论点。大多数开发人员都不明白这是怎么回事。

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

因此,为了保留单一责任原则,这种损失相关的功能应该存在于另一个类中,例如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
}