In C#, how it's possible to create custom type/cast for i.e. bool
? To better explain, i want that such expression:
bool cond=...;
int myVar= cond as customType;
so, i want customType
to behave as myVar
become either 0
or 1
, depending of cond
(if true, then 1, else 0).
Is that possible?
please, don't offer me cond ? 1 : 0
solution or others. I asked exactly what I asked, so re-read (or analyze) it if before flagging.
Yes, you can do so. If you want a custom type that behaves like a built-in type, you must take care to override some methods inherited from System.Object
. Also, you need conversion operators.
Let's create a struct called Logical
having an int
property Value
.
public readonly struct Logical : IEquatable<Logical>
{
public Logical(int value)
{
Value = value == 0 ? 0 : 1;
}
public Logical(bool cond)
{
Value = cond ? 1 : 0;
}
public int Value { get; }
... conversions and overrides
}
It has 2 constructors, allowing you to build a value from either an int
or bool
.
We can declare implicit conversions to convert between bool
and Logical
, int
and Logical
and Logical
and bool
.
public static implicit operator Logical(bool cond) => new Logical(cond);
public static implicit operator Logical(int i) => new Logical(i);
public static implicit operator bool(Logical logical) => logical.Value != 0;
It is also good to override Equals
and GetHashCode
to easily be able to compare values or to add them to dictionaries or hash sets.
public bool Equals(Logical other) // Implements IEquatable<Logical>
{
return Value.Equals(other.Value);
}
public override bool Equals(object obj)
{
if (obj is Logical logical) {
return Equals(logical);
}
return base.Equals(obj);
}
public override int GetHashCode() => Value.GetHashCode();
If you override Equals
, it is natural to overload ==
and !=
public static bool operator ==(Logical a, Logical b) => a.Value == b.Value;
public static bool operator !=(Logical a, Logical b) => a.Value != b.Value;
Finally, we override ToString
to be able to print Logicals.
public override string ToString() => Value == 0 ? "FALSE" : "TRUE";
Now, we can do these sort of things:
double x = 3.14;
Logical logical = x > 0.0;
bool b = logical;
Console.WriteLine($"logical = {logical}");
Console.WriteLine($"b = {b}");
logical = -3;
Console.WriteLine($"logical = {logical}");
Console.WriteLine($"logical.Value = {logical.Value}");
logical = 0;
Console.WriteLine($"logical = {logical}");
Console.ReadKey();
It prints:
logical = TRUE
b = True
logical = TRUE
logical.Value = 1
logical = FALSE
There is more you can do. System.Bool
, for instance, implements IComparable
, IComparable<bool>
, IConvertible
and IEquatable<bool>
. It also has static Parse
and TryParse
methods. You could also overload other operators. See: Overloadable operators (Operator overloading, C# reference).