我有一个自定义对象,它将来自旧数据库的布尔值映射到C#bool(并再次返回)。
我的自定义bool对象如下所示:
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) { ... }
答案 0 :(得分:3)
有两件事需要注意;隐式转换运算符(在S2kBool
中)到bool
,或true
/ false
运算符本身......
true / false操作符(注意我更喜欢自己的隐式bool转换):
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?
这打印为false,因为两个IsActive
字段都指向S2kBool
的相同实例。如果这是意图,那很好。但如果是我,我会让它变成不可变的(无论是类还是结构)。但是因为除了布尔之外它没有任何其他状态,我认为这非常适合作为结构。
说实话,我不是完全确定为什么它需要在所有,当所有功能都可以通过静态方法/等完成时。
答案 1 :(得分: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);
}
}