C#动态逻辑门

时间:2012-11-23 00:41:45

标签: c#

我正在开发一个允许用户从虚拟逻辑门构建数字电路的程序。每个门都是表示特定门类型的类的实例,例如,这里是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”,无论如何都是AND的中性元素)。每个输入是对另一个门的输出或bool阵列的元素(存储输入向量)的引用,以便由一个门自动生成的信号被发送到后一个门。问题是我还需要在门内动态传输信号,即如果AND门中的一个输入信号被设置为0,则输出自动具有0值。因此,当您将二进制向量馈送到cirtuit的输入时,它会更改电路输出的值。或者可能有一种更简单的模拟电路的方法,而不是从单独的门构建它?我需要它来生成测试模式。

3 个答案:

答案 0 :(得分: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的建议

答案 1 :(得分:0)

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

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

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

我会避免为Inputs属性执行此操作,因为暴露数组实际上是暴露有关类如何存储事物的信息,应该尽可能避免使用良好的OOP。例如,ReadOnlyCollection可能更合适。

但是,我会重新考虑设计,并避免使用一些任意的输入,7。你从哪里想到这个值?

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

然后你利用二进制逻辑门上的操作是关联的这一事实,因此一个AND门取a,b,c,相当于一个取a,b,将它的输出馈送到另一个也取c。这就是你在实践中构建电路的方式 - 你需要考虑的问题是门的延迟。

答案 2 :(得分: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);
        }
    }

}