假设我有一个班级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
的私有/受保护实例变量,它只使用use A
的公共接口。既然如此,我可以实现ToXml
作为扩展方法:
class A
{
// Ctor, the state, etc.
public static string ToXml(this A instance)
{
// Same deal as above
return xmlString;
}
}
扩展方法只能使用它所扩展的类的外部接口。因此,忽略扩展方法的主要用途(扩展锁定类,语义助手),SO社区对使用扩展方法的唯一目的是什么,只是为了表示方法只使用类的外部接口?
我问这个是因为我个人使用扩展方法很多 - 也许是因为我喜欢函数式编程 - 但我的同事不喜欢我这样做的理由,因为我想传达“这个特殊的方法肯定只使用类“。
的公共接口注意:这些扩展方法将替代其实例等效项。因此,扩展方法不会出现任何常见的命名空间问题。这个问题完全集中在“沟通意图”方面。
答案 0 :(得分:3)
扩展方法是Open/Closed Principle的一个示例。也就是说,它可以进行扩展,但已经关闭以进行修改。
使用Extension方法的主要好处是您不必重新编译正在扩展的类,因此需要重新编译强制相关代码。此外,通过不更改界面,您不必担心任何代码,具体取决于它的破坏。
如果你认真对待SOLID原则,那么这是一个有效的论点。大多数开发人员都不知道大惊小怪。
答案 1 :(得分:1)
您有一个类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
}