2009-02-24 42 views
2

我有一个自定义对象,从旧数据库布尔值映射到C#布尔(并再次)。处理与自定义布尔类型的比较?

我的自定义布尔对象是这样的:

public class S2kBool : IUserDefinedType { 
    public bool Value { get; set; } 

    public Type SupportedType { get { return typeof(string); } } 

    // These are the values used to represent booleans in the database 
    public const string TrueValue = "Y"; 
    public const string FalseValue = "N"; 

    public static S2kBool True { 
     get { return new S2kBool(true); } 
    } 

    public static S2kBool False { 
     get { return new S2kBool(false); } 
    } 

    public S2kBool() : this(false) { } 

    public S2kBool(bool value) { 
     this.Value = value; 
    } 

    // Called when a property of this type is populated from the database 
    public void FromSimpleDataType(object value) { 
     this.Value = value.ToString() == TrueValue; 
    } 

    // Called when a property of this type is inserted into the database 
    public object ToSimpleDataType() { 
     return this.Value ? TrueValue : FalseValue; 
    } 
} 

我希望能够做这样的事情:

public class TestObject { 
    public S2kBool IsActive = S2kBool.True; 
} 

TestObject tObj = new TestObject(); 
if (tObj.IsActive == S2kBool.True) { 
    // the above would evaluate to true 
} 

我见过之间做比较几种不同的方法对象,但我不确定要使用哪一个。

编辑:更重要的是,将有可能像做以下,并已C#比较期间处理S2kBool对象作为一个实际的布尔?它也应该允许与其他S2kBool对象进行比较。

if (tObj.IsActive == true) { ... } 

回答

2

有两件事要注意;隐式转换操作符(在S2kBool)至bool,或true/false运营商自己...


真/假运算符(注意:我宁愿隐式转换布尔自己):

public static bool operator true(S2kBool x) { 
    return x.Value; 
} 
public static bool operator false(S2kBool x) { 
    return !x.Value; 
} 

那么你可以使用if(tObj.IsActive)


转换操作符:

public static implicit operator bool(S2kBool x) { 
    return x.Value; 
} 

作品同样


您也可以在其他方向上增加一个转换:

public static implicit operator S2kBool(bool x) 
{ 
    return new S2kBool(x); 
} 

然后你就可以分配IsActive = false;


最后,我想知道这应该是一个不可变的结构?如果你期望它的行为像一个价值,那可能会令人困惑。例如,看看最后一行在这里:

TestObject obj1 = new TestObject(), 
      obj2 = new TestObject(); 
obj1.IsActive = obj2.IsActive = S2kBool.True; 

Console.WriteLine(obj1.IsActive); 
Console.WriteLine(obj2.IsActive); 

obj1.IsActive.Value = false; 

Console.WriteLine(obj1.IsActive); 
Console.WriteLine(obj2.IsActive); // what does this print? 

这将打印假的,因为这两个领域IsActive指向同实例S2kBool。如果这是意图,那很好。但如果是我,我会让它不可变(无论是类还是结构体)。但是,因为它并没有真正有一个比其他布尔任何状态,我认为这非常适合作为结构。

说实话,我并不完全肯定为什么它需要在所有,当所有的功能可以通过静态方法来完成/等

+0

谢谢!虽然,你能解释一下为什么我想让它成为一个不可变的结构吗? – 2009-02-24 21:58:18

1

是的,你可以做到这一点。您需要定义相等运算符并覆盖Equals方法。

这里是关于操作符重载的文章: http://www.csharphelp.com/archives/archive135.html

这里是重写相等运算的类型的一个例子。您可以对赋值和转换操作符进行相同操作,使您的类型可以与内置bool类型无缝协作。 (我拿你的例子,缩短了一点,以保持例子简短,并添加了相等运算符)。

public struct S2kBool : IEquatable<bool> 
{ 
    public bool Value { get; set; } 


    public bool Equals(bool other) 
    { 
     return Value == other; 
    } 

    public override int GetHashCode() 
    { 
     return Value.GetHashCode(); 
    } 

    public static bool operator ==(bool left, S2kBool right) 
    { 
     return right.Equals(left); 
    } 

    public static bool operator !=(bool left, S2kBool right) 
    { 
     return !(left == right); 
    } 

    public static bool operator ==(S2kBool left, bool right) 
    { 
     return left.Equals(right); 
    } 

    public static bool operator !=(S2kBool left, bool right) 
    { 
     return !(left == right); 
    } 

}