sma*_*man 23 c# liskov-substitution-principle immutability readonly-collection directed-acyclic-graphs
Liskov替换原则要求子类型必须满足超类型的契约.根据我的理解,这将导致ReadOnlyCollection<T>违反Liskov. ICollection<T>合同公开Add和Remove运营,但只读子类型不符合本合同.例如,
IList<object> collection = new List<object>();
collection = new System.Collections.ObjectModel.ReadOnlyCollection<object>(collection);
collection.Add(new object());
-- not supported exception
Run Code Online (Sandbox Code Playgroud)
显然需要不可变的集合.有没有关于.NET的建模方法的事情?有什么更好的方法呢? IEnumerable<T>在一个集合中做得很好,至少看起来是不可改变的.但是,语义非常不同,主要是因为IEnumerable没有明确地暴露任何状态.
在我的特定情况下,我正在尝试构建一个不可变的DAG类来支持FSM.我显然在开始时需要AddNode/ AddEdge方法,但我不希望它一旦运行就可以更改状态机.我很难表示DAG的不可变和可变表示之间的相似性.
现在,我的设计涉及预先使用DAG Builder,然后创建一次不可变图,此时它不再可编辑.Builder和具体的不可变DAG之间唯一的通用接口是Accept(IVisitor visitor).我担心,面对可能更简单的选择,这可能是过度设计/过于抽象.与此同时,我无法接受我可以在我的图形界面上公开可能NotSupportedException在客户端获得特定实现时抛出的方法.处理这个问题的正确方法是什么?
Raw*_*ing 10
您可以始终拥有(只读)图形界面,并使用读/写可修改图形界面对其进行扩展:
public interface IDirectedAcyclicGraph
{
int GetNodeCount();
bool GetConnected(int from, int to);
}
public interface IModifiableDAG : IDirectedAcyclicGraph
{
void SetNodeCount(int nodeCount);
void SetConnected(int from, int to, bool connected);
}
Run Code Online (Sandbox Code Playgroud)
(我不能弄清楚如何分割这些方法进get/ set属性的两半).
// Rubbish implementation
public class ConcreteModifiableDAG : IModifiableDAG
{
private int nodeCount;
private Dictionary<int, Dictionary<int, bool>> connections;
public void SetNodeCount(int nodeCount) {
this.nodeCount = nodeCount;
}
public void SetConnected(int from, int to, bool connected) {
connections[from][to] = connected;
}
public int GetNodeCount() {
return nodeCount;
}
public bool GetConnected(int from, int to) {
return connections[from][to];
}
}
// Create graph
IModifiableDAG mdag = new ConcreteModifiableDAG();
mdag.SetNodeCount(5);
mdag.SetConnected(1, 5, true);
// Pass fixed graph
IDirectedAcyclicGraph dag = (IDirectedAcyclicGraph)mdag;
dag.SetNodeCount(5); // Doesn't exist
dag.SetConnected(1, 5, true); // Doesn't exist
Run Code Online (Sandbox Code Playgroud)
这就是我希望Microsoft用他们的只读集合类做的 - 为get-count,get-by-index行为等创建一个接口,并通过添加,更改值等接口扩展它.
| 归档时间: |
|
| 查看次数: |
862 次 |
| 最近记录: |