【问题标题】:Best practice for recursive class递归类的最佳实践
【发布时间】:2014-12-20 06:55:19
【问题描述】:

问题:

我想为自定义dice 构建一个类。但它还应提供以下内容:

  1. 每个side 可以包含另一个dice
  2. sides 的数量应该是动态可扩展的,但必须至少包含一个
    • 逻辑上dice 需要有一个currentSide
  3. 每个side 都有一个property,它提供了这一面的内容(在D6 上为"4"

到目前为止一切顺利,我创建了两个类diceside,并为他们提供了我认为他们需要的属性。

public class Side
{
    //public bool HasDice { get { return Dice != null; } } - Removed not needed
    public Dice Dice { get; set; }
    public string Value { get; set; }
}

public class Dice
{
    public ObservableCollection<Side> Sides { get; set; }
    public string Name { get; set; }
    public Side CurrentSide { get; set; }
}

是这样吗,我从来没有做过任何递归类所以我不确定?

另外,我如何检测相同的骰子和面是否“无休止地”指代它们自己。

喜欢:

D1.CurrentSide = Side1; Side1.Dice = D1;

我应该在构建对象时检查这个吗?

编辑:

  • 如果 D1 掷出 S2,则不应掷出 D2。还有D2.Dice = Null

  • 如果 D1 掷出 S1,则应掷出 D2。

  • 如果 D2 掷出 S1,则应掷出 D3。

  • 如果 D2 掷出 S2,则应掷出 D4。

D3 和 D4 不应触发任何滚动。

【问题讨论】:

  • 抛开良好的编程习惯不谈,这个设计是谁提出的?公共财产说一方是否有骰子?这对你有任何意义吗?
  • Side 中的Dice 引用是指该面所属的骰子,还是您实际上在其他骰子之上有骰子?
  • 也许它是一个超级骰子,所以每一边都有另一个骰子? @NielsKeurentjes 这太不专业了+1。
  • 所以Side.Dice 可以选择引用任何Dice,除了它包含的Dice

标签: c# class recursion self-reference dice


【解决方案1】:

您正在制作的内容称为state machine。您的程序(“机器”)始终处于某种状态,但可以由于执行某些操作而改变状态。根据逻辑,机器可以多次处于相同状态是完全可以接受的。所以,我不会太在意机器逻辑中的循环。如果用户想要循环,那么就让他拥有它,只要机器可以达到某种最终状态并且程序到达执行结束。

【讨论】:

    【解决方案2】:

    根据你所说的,我建议你创建一个骰子的对象图,其中一个骰子通过连接到其他骰子,然后运行拓扑排序算法来揭示循环依赖关系。

    为此,我建议您自己编写,使用QuickGraph 工具。

    现在,我自己曾经使用过它并为IEnumerable 写了一个扩展,它返回排序IList,其中返回的第一个项目是其他项目从未引用的项目。后者是引用最多的。 (或者可能反过来。)在循环依赖的情况下,抛出异常。我的扩展使用 QuickGraph 库。

    public static IList<T> OrderTopologically<T>(this IEnumerable<T> e, Func<T, IEnumerable<T>> dependenciesSelector)
    {
        var graph = new AdjacencyGraph<T, Edge<T>>();
    
        foreach (T item in e)
        {
            graph.AddVertex(item);
    
            foreach (T dependecy in dependenciesSelector(item))
            {
                graph.AddEdge(new Edge<T>(item, dependecy));
            }
        }
    
        var topSort = new TopologicalSortAlgorithm<T, Edge<T>>(graph);
    
        try
        {
            topSort.Compute();
        }
        catch (NonAcyclicGraphException cyclicException)
        {
            throw new ElQueueException("Circular reference detected while processing javascript dependency order.", cyclicException);
        }
        catch (KeyNotFoundException keyNotFoundException)
        {
            throw new ElQueueException("Dependency could not be found.", keyNotFoundException);
        }
    
        return topSort.SortedVertices;
    }
    

    【讨论】:

    • 我用一张图片更新了我的帖子,说明我希望骰子如何表现,这可以通过对象图来实现吗?如果是这样,我会阅读更多内容。 :)
    猜你喜欢
    • 2011-02-13
    • 2015-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2014-03-02
    • 2013-11-12
    相关资源
    最近更新 更多