在C#中,如何为bool
创建自定义类型/类型?为了更好地解释,我想要这样的表达:
bool cond=...;
int myVar= cond as customType;
因此,我希望customType
的行为就像myVar
变成0
或1
一样,取决于cond
(如果为true,则为1,否则为0 )。
有可能吗?
请不要向我提供cond ? 1 : 0
解决方案或其他解决方案。我确切地问了我要问的内容,因此如果在标记之前重新阅读(或分析)它。
答案 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个构造函数,可让您从int
或bool
来构建值。
我们可以声明隐式转换,以在bool
和Logical
,int
和Logical
和Logical
和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;
最好覆盖Equals
和GetHashCode
以方便地比较值或将其添加到字典或哈希集。
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
实现IComparable
,IComparable<bool>
,IConvertible
和IEquatable<bool>
。它还具有静态Parse
和TryParse
方法。您还可以使其他运算符超载。参见: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()}");