以前的文章中,我们讨论了三值逻辑可能的运算体系和可能的代码实现。这里,我们给出一种完全的实现方式。以下代码利用枚举,在每一个三值逻辑对象中标识出其认可的算法,如果两个对象认可的与/或算法不一致,则抛出异常。出于程序结构上的完整性限制,逻辑对象具有默认算法——Arithmetics.Mathemetic。但是,我们可以在运行期修改它这个标识,也可以通过工厂方法方便的得到指定算法的对象。 以下为算法标识枚举Arithmetics的定义: public enum Arithmetics {Mathematic, Database, Verify}; 以下为三值逻辑结构的代码,从不同的与/或运算静态方法的名字上,我们可以看出它们支持的算法。当然,如您所见,这种设计结构是封闭的,我们不能为它添加新的算法——从实用角度上看,这三种算法已经可以应付几乎所有场合了。 public struct VarBool { // The three possible Boolw3 values. public static readonly VarBool Null = new VarBool(0); public static readonly VarBool False = new VarBool(-1); public static readonly VarBool True = new VarBool(1); // private field that stores –1, 0, 1 for False, Null, True. private sbyte value; private Arithmetics _Arithmetic; public Arithmetics Arithmetic { get { return _Arithmetic; } set { _Arithmetic = value; } }
// private instance constructor. The value parameter must be –1, 0, or 1. private VarBool(int value) { this.value = (sbyte)value; this._Arithmetic = Arithmetics.Mathematic; }
/// <summary> /// 从数据库组件的逻辑字段值中构造实例 /// </summary> /// <param name="value">只能为System.Boolean或DBNull类型。</param> public static VarBool Read(object value) { if(null == value) throw new ArgumentException("The value is null!"); if(value is bool || value is DBNull) return (VarBool)value; else throw new ArgumentException("The value must in true, false or DBNull!"); }
/// <summary> /// 从字符串解析值。 /// </summary> /// <param name="value">可选值为"True"、"False"、"Null"</param> public static VarBool Parse(string value) { switch(value) { case "True" : { return True; } case "False": { return False; } case "Null": { return Null; } default: throw new ArgumentException("The value must in \"True\", \"False\" or \"Null\"!"); } }
// Properties to examine the value of a Boolw3. Return true if this // Boolw3 has the given value, false otherwise. public bool IsNull { get { return value == 0; } } public bool IsFalse { get { return value < 0; } } public bool IsTrue { get { return value > 0; } } // Implicit conversion from bool to Boolw3. Maps true to Boolw3.True and // false to Boolw3.False. public static implicit operator VarBool(bool x) { return x? True: False; }
public static implicit operator VarBool(DBNull x) { return Null; }
// Explicit conversion from Boolw3 to bool.Throws an exception if the // given Boolw3 is Null, otherwise returns true or false. public static explicit operator bool(VarBool x) { if (x.value == 0) throw new InvalidOperationException(); return x.value > 0; }
public static explicit operator DBNull(VarBool x) { if (x.value != 0) throw new InvalidOperationException(); return DBNull.Value; }
// Equality operator. Returns Null if either operand is Null, otherwise // returns True or False. public static VarBool operator ==(VarBool x, VarBool y) { if (x.value == 0 || y.value == 0) return Null; return x.value == y.value? True: False; } // Inequality operator. Returns Null if either operand is Null, otherwise // returns True or False. public static VarBool operator !=(VarBool x, VarBool y) { if (x.value == 0 || y.value == 0) return Null; return x.value != y.value? True: False; } // Logical negation operator. Returns True if the operand is False, Null // if the operand is Null, or False if the operand is True. public static VarBool operator !(VarBool x) { return new VarBool(-x.value); }
public override bool Equals(object obj) { return base.Equals (obj); } public override int GetHashCode() { return this.value; } public override string ToString() { if (value > 0) return "True"; if (value < 0) return "False"; return "Null"; }
public static VarBool MathAnd(VarBool x, VarBool y) { return new VarBool(x.value < y.value? x.value: y.value); }
public static VarBool MathOr(VarBool x, VarBool y) { return new VarBool(x.value > y.value? x.value: y.value); }
public static VarBool DBAnd(VarBool x, VarBool y) { if (x.value == 0 || y.value ==0) return Null; return new VarBool(x.value < y.value ? x.value : y.value); } public static VarBool DBOr(VarBool x, VarBool y) { if (x.value == 0 || y.value ==0) return Null; return new VarBool(x.value > y.value ? x.value : y.value); }
public static VarBool VerifyAnd(VarBool x, VarBool y) { if (x.value == -1 || y.value == -1) return False; if (x.value == 1 || y.value == 1) return True; return Null; } public static VarBool VerifyOr(VarBool x, VarBool y) { if (x.value == 1 || y.value == 1) return True; if (x.value == -1 & y.value == -1) return False; return True; }
public static VarBool operator &(VarBool x, VarBool y) { if(x.Arithmetic != y.Arithmetic) throw new ArgumentException(string.Format("左参数选择了{0}算法,而右参数选择了{1}算法。", x.Arithmetic, y.Arithmetic)); switch(x.Arithmetic) { case Arithmetics.Database: return DBAnd(x, y); case Arithmetics.Mathematic: return MathAnd(x, y); case Arithmetics.Verify: return VerifyAnd(x, y); default: return Null; } }
public static VarBool operator |(VarBool x, VarBool y) { if(x.Arithmetic != y.Arithmetic) throw new ArgumentException(string.Format("左参数选择了{0:D}算法,而右参数选择了{1:D}算法。", x.Arithmetic, y.Arithmetic)); switch(x.Arithmetic) { case Arithmetics.Database: return DBOr(x, y); case Arithmetics.Mathematic: return MathOr(x, y); case Arithmetics.Verify: return VerifyOr(x, y); default: return Null; } }
}
以下为三值逻辑类的工厂方法类。通过工厂类的构造函数参数,我们可以指定即将生成的三值逻辑对象支持何种算法,这使得我们可以通过更简单和直观的方式生成对象。 /// <summary> /// VarBool 的工厂方法集合,封装算法选择。 /// 如果不通过该工厂生成VarBool,其默认算 /// 法为Mathematic,也可以在运行期修改 /// Arithmetic属性来指定算法。 /// </summary> public class VarBoolBuilder { private Arithmetics _Arithmetic; public VarBoolBuilder(Arithmetics Arithmetic) { _Arithmetic = Arithmetic; } public VarBool Null { get { VarBool re = VarBool.Null; re.Arithmetic = _Arithmetic; return re; } } public VarBool True { get { VarBool re = VarBool.True; re.Arithmetic = _Arithmetic; return re; } } public VarBool False { get { VarBool re = VarBool.False; re.Arithmetic = _Arithmetic; return re; } } public VarBool Read(object value) { VarBool re = VarBool.Read(value); re.Arithmetic = _Arithmetic; return re; } public VarBool Parse(string value) { VarBool re = VarBool.Parse(value); re.Arithmetic = _Arithmetic; return re; } }

|