2009-02-24 3 views
2

У меня есть пользовательский объект, который отображает логическое значение из старой базы данных в 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 
} 

Я видел несколько различных способов делать сравнения между объектов, но я не уверен, какой из них использовать.

EDIT: Еще лучше, можно ли сделать что-то вроде следующего и иметь C# рассматривать объект S2kBool в качестве фактического булева во время сравнения? Он также должен позволять сравнивать с другими объектами S2kBool.

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

ответ

2

На данный момент есть 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. Если это было намерение, то прекрасно. Но если бы это был я, я бы сделал его неизменным (будь то класс или структура). Но поскольку на самом деле у него нет никакого состояния, кроме bool, я бы сказал, что это хорошо подходит как структура.

Честно говоря, я не совсем уверен, почему это необходимо на всех, когда все функции можно было бы сделать с помощью статических методов/и т.д.

+0

Спасибо! Хотя, не могли бы вы объяснить, почему я могу сделать эту неизменяемую структуру? –

+0

Я отредактирую, чтобы проиллюстрировать (слишком длинный комментарий). –

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); 
    } 

} 
Смежные вопросы