如何为布尔创建1/0返回类型?

时间:2019-11-24 14:41:43

标签: c# casting typecasting-operator

在C#中,如何为bool创建自定义类型/类型?为了更好地解释,我想要这样的表达:

bool cond=...;
int myVar=  cond as customType;

因此,我希望customType的行为就像myVar变成01一样,取决于cond(如果为true,则为1,否则为0 )。

有可能吗?


请不要向我提供cond ? 1 : 0解决方案或其他解决方案。我确切地问了我要问的内容,因此如果在标记之前重新阅读(或分析)它。

3 个答案:

答案 0 :(得分:3)

是的,您可以这样做。如果您想要一个自定义类型,其行为类似于内置类型,则必须注意重写从System.Object继承的某些方法。另外,您需要转换运算符。

让我们创建一个名为Logical的结构,该结构具有一个int属性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
}

它具有2个构造函数,可让您从intbool来构建值。

我们可以声明隐式转换,以在boolLogicalintLogicalLogicalbool之间进行转换。

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;

最好覆盖EqualsGetHashCode以方便地比较值或将其添加到字典或哈希集。

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

如果您覆盖Equals,自然会重载==!=

public static bool operator ==(Logical a, Logical b) => a.Value == b.Value;
public static bool operator !=(Logical a, Logical b) => a.Value != b.Value;

最后,我们将覆盖ToString以打印逻辑文档。

public override string ToString() => Value == 0 ? "FALSE" : "TRUE";

现在,我们可以做以下事情:

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

它打印:

logical = TRUE
b       = True
logical = TRUE
logical.Value = 1
logical = FALSE

您还可以做更多的事情。例如,System.Bool实现IComparableIComparable<bool>IConvertibleIEquatable<bool>。它还具有静态ParseTryParse方法。您还可以使其他运算符超载。参见:Overloadable operators (Operator overloading, C# reference)

答案 1 :(得分:0)

答案here可能是您应该使用的答案,除非您有充分的理由不这样做。

但是,只是因为它很有趣,您可以选择使用以下结构的某些版本,以便隐式进行转换,并且可以同时使用bool值和int值,而无需任何额外的内存使用:

[StructLayout(LayoutKind.Explicit)]
public struct BoolToInt
{
    [FieldOffset(0)]
    public readonly bool booleanValue;

    [FieldOffset(0)]
    public readonly int integerValue;

    public BoolToInt(bool booleanValue)
    {
        this.integerValue = 0; //irrelevant, will be overwritten, but the compiler can't figure this out
        this.booleanValue = booleanValue;
    }
}

如果希望更改布尔值,可以使它可变,但这确实违反了结构用法的一般原则。
我强烈建议不要使integerValue字段可变。

答案 2 :(得分:-2)

如果需要布尔值(1或0),则应使用GetHashCode函数 Boolea.GetHashCode

我在这里举了一个例子

bool v1 = true;
bool v2 = false;
int res;

Console.WriteLine($"v1: {v1.GetHashCode()}, v2: {v2.GetHashCode()}");