程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 三值邏輯的C#實現

三值邏輯的C#實現

編輯:.NET實例教程

C#中的三值邏輯類
三值邏輯的實際應用價值並未被忽視,在絕大多數介紹關系型數據庫知識的書籍中,都涉及了NULL值的討論,也少不了三值邏輯。而MSDN中,則給出了一個用C#實現的三值邏輯結構(struct),在應用層提供了三值邏輯運算功能。相關文章轉貼如下:







C# Language Specification



11.4.2 Database boolean type






The DBBool struct below implements a three-valued logical type. The possible values of this type are DBBool.True, DBBool.False, and DBBool.Null, where the Null member indicates an unknown value. Such three-valued logical types are commonly used in databases.

using System;
public struct DBBool
{
// The three possible DBBool values.
public static readonly DBBool Null = new DBBool(0);
public static readonly DBBool False = new DBBool(-1);
public static readonly DBBool True = new DBBool(1);
// Private fIEld that stores –1, 0, 1 for False, Null, True.
sbyte value;
// Private instance constructor. The value parameter must be –1, 0, or 1.
DBBool(int value) {
this.value = (sbyte)value;
}
// PropertIEs to examine the value of a DBBool. Return true if this
// DBBool 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 DBBool. Maps true to DBBool.True and
// false to DBBool.False.
public static implicit Operator DBBool(bool x) {
return x? True: False;
}
// Explicit conversion from DBBool to bool. Throws an exception if the
// given DBBool is Null, otherwise returns true or false.
public static explicit Operator bool(DBBool x) {
if (x.value == 0) throw new InvalidOperationException();
return x.value > 0;
}
// Equality operator. Returns Null if either Operand is Null, otherwise
// returns True or False.
public static DBBool Operator ==(DBBool x, DBBool 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 DBBool Operator !=(DBBool x, DBBool 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 DBBool Operator !(DBBool x) {
return new DBBool(-x.value);
}
// Logical AND operator. Returns False if either Operand is False,
// otherwise Null if either Operand is Null, otherwise True.
public static DBBool Operator &(DBBool x, DBBool y) {
return new DBBool(x.value < y.value? x.value: y.value);
}
// Logical OR operator. Returns True if either Operand is True, otherwise
// Null if either Operand is Null, otherwise False.
public static DBBool Operator |(DBBool x, DBBool y) {
return new DBBool(x.value > y.value? x.value: y.value);
}
// Definitely true operator. Returns true if the Operand is True, false
// otherwise.
public static bool Operator true(DBBool x) {
return x.value > 0;
}
// Definitely false operator. Returns true if the Operand is False, false
// otherwise.
public static bool Operator false(DBBool x) {
return x.value < 0;
}
public override bool Equals(object obj) {
if (!(obj is DBBool)) return false;
return value == ((DBBool)obj).value;
}
public override int GetHashCode() {
return value;
}
public override string ToString() {
if (value > 0) return "DBBool.True";
if (value < 0) return "DBBool.False";
return "DBBool.Null";
}
}




--------------------------------------------------------------------------------

Send feedback on this topic to Microsoft

&copy; Microsoft Corporation. All rights reserved.

從文章內容我們可以看出,它采用的是我們前面所述的第三種算法。這個示例搭建了一個不錯的框架,除了與、或運算,還包括了必要的類型轉換、比較以及在.Net CLR中必不可少的GetHashCode和ToString方法。

當我們以初學者的心態面對這段樸實的代碼時,有幾個地方是值得學習的:

在結構內部,以-1、0、1來代表三種不同的邏輯狀態。並通過定義False、NULL、True三個常量來代表所有可能該類型對象所有可能的值。這種數值與邏輯的對應符合人們常規的思維習慣和數學上的美感。也方便實現GetHashCode方法。

利用內部數值,簡潔美觀的實現了與/或/非運算。如果按照前面我們提的三種邏輯算法中的另外兩種,實現起來就沒有那麼美觀了。也許這就是很多關系型數據庫選擇這種算法實現的原因。美感,在數學體系中是一件很重要的事。

提供了IsTrue、IsFalse、IsNull判斷功能,使用起來很方便。

三值邏輯向兩值邏輯和DBNull轉換時,必須顯示轉型(explicit),反之則只需要隱式轉換(implicit)。

實現了true和false運算符。

重載了.Net CLR要求的GetHashCode和ToString方法。當我們在特定的環境工作時,應該遵循該環境的要求和約定,而這是實際開發時經常被忽視的。

為了滿足實際使用的需要,我對這個類進行了一些擴充。主要如下:

與DBNULL類型的互相轉化(要考慮其中的類型轉換異常)。

從字符串到三值邏輯的解析方法Parse(據此對ToString()方法有所改變)。

增加了新的構造函數。

增加了支持另外兩種邏輯運算體系的與/或運算。

增加了向數據庫邏輯字段賦值所用的轉換函數ToDBBoolean。

新的代碼如下:

using System;

namespace March.VBoolean
{
/// <summary>
/// 三值邏輯類(Bool with three),支持System.DBNull。
/// </summary>
public struct Boolw3
{
// The three possible Boolw3 values.
public static readonly Boolw3 Null = new Boolw3(0);
public static readonly Boolw3 False = new Boolw3(-1);
public static readonly Boolw3 True = new Boolw3(1);
// Private fIEld that stores –1, 0, 1 for False, Null, True.
sbyte value;
// Private instance constructor. The value parameter must be –1, 0, or 1.
Boolw3(int value)
{
this.value = (sbyte)value;
}

public Boolw3(bool value)
{
this.value = value? (sbyte)1:(sbyte)-1;
}
public Boolw3(DBNull value)
{
this.value = (sbyte)0;
}
/// <summary>
/// 從數據庫組件的邏輯字段值中構造實例
/// </summary>
/// <param name="?">只能為System.Boolean或DBNull類型。</param>
public Boolw3(object value)
{
if(null == value)
throw new ArgumentException("The value must in true, false or DBNull!");
if(value.GetType() == typeof(bool))
{
this.value = (bool)value?(sbyte)1:(sbyte)-1;
return;
}
if(value.GetType() == typeof(DBNull))
{
this.value = (sbyte)0;
return;
}
throw new ArgumentException("The value must in true, false or DBNull!");
}
/// <summary>
/// 從字符串解析值。
/// </summary>
/// <param name="value">可選值為可能帶有限定名"Boolw3"的"True"、"False"、"Null"</param>
public static Boolw3 Parse(string value)
{
Boolw3 Re = Null;
switch(value)
{
case "Boolw3.True":
case "True" :
{
Re.value = (sbyte)1;
break;
}
case "Boolw3.False":
case "False":
{
Re.value = (sbyte)-1;
break;
}
case "Boolw3.Null":
case "Null":
{
Re.value = (sbyte)0;
break;
}
default:
throw new ArgumentException("The value must in \"Boolw3.True\", \"Boolw3.False\" ,\"Boolw3.Null\", \"True\", \"False\" or \"Null\"!");
}
return Re;
}
// 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 Boolw3(bool x)
{
return x? True: False;
}

public static implicit Operator Boolw3(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(Boolw3 x)
{
if (x.value == 0) throw new InvalidOperationException();
return x.value > 0;
}

public static explicit Operator DBNull(Boolw3 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 Boolw3 Operator ==(Boolw3 x,Boolw3 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 Boolw3 Operator !=(Boolw3 x, Boolw3 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 Boolw3 Operator !(Boolw3 x)
{
return new Boolw3(-x.value);
}
// Logical AND operator. Returns False if either Operand is False,
// otherwise Null if either Operand is Null, otherwise True.
public static Boolw3 Operator &(Boolw3 x, Boolw3 y)
{
return new Boolw3(x.value < y.value? x.value: y.value);
}
// Logical OR operator. Returns True if either Operand is True, otherwise
// Null if either Operand is Null, otherwise False.
public static Boolw3 Operator |(Boolw3 x, Boolw3 y)
{

return new Boolw3(x.value > y.value? x.value: y.value);
}

/// <summary>
/// VerifyAnd事實上是一種以Null值為最低優先級的邏輯與操作。通常用於驗證數據有效性。
/// 兩個操作數中至少有一個為False時返回False,否則,至少有一個為True時為True,否
/// 則返回NULL。
/// </summary>
/// <param name="x">左操作數</param>
/// <param name="y">右操作數</param>
/// <returns>運算結果為Boolw3類型</returns>
public static Boolw3 VerifyAnd(Boolw3 x, Boolw3 y)
{
if (x.value == -1 || y.value == -1) return False;
if (x.value == 1 || y.value == 1) return True;
return Null;
}

/// <summary>
/// VerifyOr事實上是一種以Null值為最低優先級的邏輯或操作。通常用於驗證數據有效性。
/// 兩個操作數中至少有一個為True時返回True,否則,至少有一個為False時返回False,否
/// 則返回NULL。
/// </summary>
/// <param name="x">左操作數</param>
/// &lt;param name="y">右操作數</param>
/// <returns>運算結果為Boolw3類型</returns>
public static Boolw3 VerifyOr(Boolw3 x,Boolw3 y)
{
if (x.value == 1 || y.value == 1) return True;
if (x.value == -1 & y.value == -1) return False;
return True;
}

/// <summary>
/// DBAnd是以Null值為最高優先值的邏輯與操作,常見於某些數據庫平台。當操作數中有一個為
/// Null,返回值為Null,其它與二值邏輯相同。
/// </summary>
/// <param name="x">左操作數</param>
/// <param name="y">右操作數</param>
/// <returns>運算結果為Boolw3類型</returns>
public static Boolw3 DBAnd(Boolw3 x, Boolw3 y)
{
if (x.value == 0 || y.value ==0) return Null;
return new Boolw3(x.value < y.value ? x.value : y.value);
}

/// <summary>
/// DBOr是以Null值為最高優先值的邏輯或操作,常見於某些數據庫平台。當操作數中有一個為
/// Null,返回值為Null,其它與二值邏輯相同。
/// </summary>
/// <param name="x">左操作數</param>
/// <param name="y">右操作數</param>
/// <returns>運算結果為Boolw3類型</returns>
public static Boolw3 DBOr(Boolw3 x, Boolw3 y)
{
if (x.value == 0 || y.value ==0) return Null;
return new Boolw3(x.value > y.value ? x.value : y.value);
}

// Definitely true operator. Returns true if the Operand is True, false
// otherwise.
public static bool Operator true(Boolw3 x)
{
return x.value > 0;
}
// Definitely false operator. Returns true if the Operand is False, false
// otherwise.
public static bool Operator false(Boolw3 x)
{
return x.value < 0;
}
public override bool Equals(object obj)
{
if (!(obj is Boolw3)) return false;
return value == ((Boolw3)obj).value;
}
public override int GetHashCode()
{
return value;
}
public override string ToString()
{
if (value > 0) return "Boolw3.True";
if (value < 0) return "Boolw3.False";
return "Boolw3.Null";
}

/// <summary>
/// 用於向數據庫訪問組件的Boolean類型(如SqlDBType.Bit)字段賦值
/// </summary>
/// <returns>返回一個object對象,其內部封裝的可能為true、false或DBNull.Value</returns>
public object ToDbBoolean()
{
return (value == 0) ? (object)DBNull.Value : (object)(value>0);
}
}
}


以上代碼經實際應用,可以滿足需求,但是有如下地方還值得進一步改造:

應當將三種邏輯體系放在同一個類型中實現顯得很不協調,影響了代碼一致性和我們的常規使用習慣。應當將通用的代碼統一生成為一個基類,並用抽象方法或接口的形式規定出與/或運算實現。在三個不同的子類中實現。並在子類中實現不同子類之間的顯示類型轉換。為了出現不必要的強耦合,可以實現子類向基類的隱式類型轉換(由於OO語言的特性,這一點默認情況下就是有效的)以及基類向子類的顯式類型轉換(這一點可以通過在基類中定義一個虛構造函數,由子類直接繼承實現)。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved