1

我正在开发一个允许用户从虚拟逻辑门构建数字电路的程序。每个门都是代表特定门类型的类的实例,例如,AND 类的外观如下:

public class andgate
{
    public andgate()
    {
        inputs = new bool[7];
        for (int i = 0; i < 7; i++) inputs[i] = true;
        output = (inputs[0] && inputs[1] && inputs[2] && inputs[3] && inputs[4] && inputs[5] && inputs[6]);
    }
    public bool[] inputs;
    public bool output;
}

每个门都有七个输入,但并非所有输入都必须使用(即,对于具有三个输入的门,其余四个将只是“1”,无论如何都是与的中性元素)。每个输入都是对另一个门的输出或布尔数组(存储输入向量)的元素的引用,以便一个门生成的信号自动发送到下一个门。问题是我还需要在门内动态传输信号,即如果与门中的输入信号之一设置为 0,则输出自动具有 0 值。因此,当您将二进制向量输入到电路的输入时,它会改变电路输出的值。或者也许有比从单个门构建电路更简单的方法来模拟电路?我需要它来生成测试模式。

4

3 回答 3

4

output属性设为只读:

public bool output
{
    get
    {
        return inputs.All(i => i);
    }
}

无需对所有输入进行 AND 运算,只需检查是否有任何输入为假。

当然,您必须删除output构造函数中的赋值。这应该使您的output财产“动态”。

您可能还希望将输入更改为bool?[],以便一个null值表示没有信号。然后,您必须将输入数组的初始化全部删除为 true,并将输出返回更改为:

return inputs.All(i => i.GetValueOrDefault(true));

在评论中编辑了 Tim S 的建议

于 2012-11-23T00:55:15.833 回答
0

为此,您应该使用属性来设置/获取输入,因为您可以在属性中执行额外的计算。您持有的状态变量应该是私有的。

public bool[] Inputs {
    set {
        inputs = value;
    }
}

public bool Output {
    get {
        return inputs[0] && inputs[1] ...
    }
}

我会避免对 Inputs 属性执行此操作,因为公开数组实际上是公开有关类如何存储事物的信息,对于良好的 OOP,应尽可能避免这样做。例如,ReadOnlyCollection 可能更合适。

但是,我会重新考虑总体设计,并避免使用任意数量的输入,7. 你从哪里变出这个值?

一种更简单的方法是假设一个门有 2 个值 - A 和 B,您可以在构造函数或单个属性中为其设置值。

然后,您可以利用二进制逻辑门上的操作是关联的这一事实,因此采用 a、b、c 的 AND 门等效于采用 a、b 并将其输出馈送到另一个也采用 c 的门。无论如何,这就是您在实践中构建电路的方式-您需要考虑的问题是门的延迟。

于 2012-11-23T01:00:37.833 回答
0

听起来您应该在门中添加事件,这样当它们的状态发生变化时,它们就能够通知依赖对象;像这样的东西:

public class AndGate
{

    private bool[] inputs;
    private bool output;

    public bool[] Inputs 
    {
        get
        {
            return this.inputs;
        }
        set
        {
            this.inputs = value; 
            UpdateOutput();     
        }
    }
    public bool Output
    {
        get
        {
            return this.output;
        }
    }

    public AndGate()
    {
        inputs = new bool[7];
        for (int i = 0; i < 7; i++) inputs[i] = true;
        UpdateOutput();
    }

    private void UpdateOutput()
    {
        bool original = output;
        output = true;
        for(int i=0; i<inputs.Length; i++)
        {
            output = output && inputs[i];
        }
        if (original != output)
        {
            OnChanged(EventArgs.Empty);
        }
    }

    public event GateStateChangedEventHandler StateChanged;  
    protected virtual void OnChanged(EventArgs e) 
    {
        if (StateChanged != null) 
        {
            StateChanged(this, e);
        }
    }

}
于 2012-11-23T01:03:46.880 回答