C#"无法在接口中指定构造函数/静态方法"问题所需的正确解决方案

Kev*_*ice 3 c#

好的,我需要一些帮助.

这是旧的"不能使用接口来强制构造函数/静态方法"的问题.

什么是合适的设计呢?

我有一组数据实体(实体框架的东西),我为此编写了部分类方法来转换为XML(XElement对象).

我有一个实例方法来"保存"XML:

// Convert entity to XML
public XElement ToXml() {}
Run Code Online (Sandbox Code Playgroud)

...我有一个"读取"XML的构造函数:

// Create entity from XML constructor.
public MyEntity(XElement) {}
Run Code Online (Sandbox Code Playgroud)

或者,我可以使用静态工厂方法来"读取"XML:

public static MyEntity ParseXml(XElement) {}
Run Code Online (Sandbox Code Playgroud)

困境:

  1. 我可以创建一个强制执行"保存" ToXml()方法的界面,但如果它只解决了一半的问题呢?接口无法强制执行任何"加载"方法.

  2. 我可以依靠自己的良好意图来创建这些方法,而不需要任何合同.

  3. 我可以创建充满了像冗余方法静态类XmlToEntity1()XmlToEntity2()等...(现在我已经描述了良好的"仿制药"的问题).不过,具体的转换代码(这是具体到每一个实体)将创建单独的方法或每个开关/ case并且似乎属于实体类,而不是在其他一些类中,不是吗?

如果有经验的C#编码器可以为这个常见问题展示一个好的设计,我想我会从中学到很多东西.

七月四日快乐!

可能的解决方案1

XmlSerializer具有两个静态泛型方法的单个类:

public static T Deserialize<T>(XElement xml) {}
public static XElement Serialize<T>(T entity) {}
Run Code Online (Sandbox Code Playgroud)
  • Pro:只有一个类(不需要接口)
  • Pro:将序列化责任与实体类分开.
  • Con:对于支持的每种实体类型,仍然需要单独的方法或开关/案例块.
  • 骗局:?不可扩展 - 每次实体更改或添加/删除时都必须修改此类.

可能的经验教训?

"不能使用构造函数和静态方法的接口"问题可能是以下症状:

  1. 违反SRP(单一责任委托人).
  2. 违反SoC(关注分离)主体.

Tor*_*ørn 5

如何使用简单的实例方法从XML加载?您的界面将是这样的:

public interface XmlSerializableEntity
{
   XElement Serialize(); // or ToXml() if you prefer..
   void Deserialize(XElement e); // or Load() or something like that..
}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用通用解决方案:

public interface Serializable<T>
{
   T Serialize();
   void Deserialize(T e);
}
Run Code Online (Sandbox Code Playgroud)

缺点是您必须在加载实体对象之前对其进行初始化,这可能意味着您将使对象处于无效状态.但我相信这是一种常见的模式.