假设我有一个包含布尔值列表的类,并且我想要一个报告它们是否都为"true"的属性。有几种方法可以做到这一点:
class BunchOfBools
{
List<bool> Stuff = new List<bool>();
bool AllAreTrue1 => Stuff.All(b => b);
bool AllAreTrue2 => Stuff.TrueForAll(b => b);
}
酷。生活是美好的。
但现在我意识到我有一个类实现了"operator true"one_answers"operator false">
class BatteryIsGood
{
float BatteryVoltage;
public static bool operator true(BatteryIsGood ab) => ab.BatteryVoltage >= 3;
public static bool operator false(BatteryIsGood ab) => ab.BatteryVoltage < 3;
}
如果我有一堆"BatteryIsGood"对象(是的,这是一个人为的例子(,并且我想使用BunchOfBools来检查它们是否都是好的,那么就让BunchOfBools通用化:
class BunchOfBools<T>
{
List<T> Stuff = new List<T>();
bool AllAreTrue1 => Stuff.All(b => b);
bool AllAreTrue2 => Stuff.TrueForAll(b => b);
bool AllAreTrue3 => Stuff.All(b => (bool)b);
bool AllAreTrue4 => Stuff.TrueForAll(b => (bool)b);
bool AllAreTrue5
{
get
{
foreach (T one in Stuff)
{
if (!one)
return false;
}
return true;
}
}
bool AllAreTrue6 => Stuff.All(b => (bool)(object)b);
bool AllAreTrue7 => Stuff.TrueForAll(b => (bool)(object)b);
}
BunchOfBools<BatteryIsGood> allBatteriesAreGood;
当然,编译器对泛型BunchOfBools一点也不满意(函数1到5不编译(,因为"无法将类型't'转换为bool"。AllAreTrue6和AllAreTrue7编译,但(1(丑陋,(2(效率低下,(3(类型不安全(直到运行时你才会发现"t"无法转换为布尔(。
有没有办法添加一个通用约束,说"T必须实现运算符true"?
编辑
甚至可以合理地说,类必须实现到bool的隐式转换,如果这有帮助的话:
class BatteryIsGood
{
float BatteryVoltage;
public static bool operator true(BatteryIsGood ab) => (bool)ab;
public static bool operator false(BatteryIsGood ab) => !((bool)ab);
public static implicit operator bool(BatteryIsGood big) => ab.BatteryVoltage >= 3;
}
您可以使用ToString和Parse的组合,如下所示:
class BunchOfBools<T>
{
List<T> Stuff = new List<T>();
bool AllAreTrue1 => Stuff.All(b => bool.Parse(b.ToString()));
bool AllAreTrue2 => Stuff.TrueForAll(b => bool.Parse(b.ToString()));
bool AllAreTrue3 => Stuff.All(b => (bool)bool.Parse(b.ToString()));
bool AllAreTrue4 => Stuff.TrueForAll(b => (bool)bool.Parse(b.ToString()));
bool AllAreTrue5
{
get
{
foreach (T one in Stuff)
{
if (!bool.Parse(one.ToString()))
return false;
}
return true;
}
}
bool AllAreTrue6 => Stuff.All(b => (bool)(object)b);
bool AllAreTrue7 => Stuff.TrueForAll(b => (bool)(object)b);
}