C# 重载的false运算符何时执行,它有什么好处?
我一直在搜索实际工作的代码,其中实际执行了重载的C# 重载的false运算符何时执行,它有什么好处?,c#,operator-overloading,C#,Operator Overloading,我一直在搜索实际工作的代码,其中实际执行了重载的false操作符 有些相同,但接受的答案链接到返回404错误的url。我也看了一些其他的问题 我在几乎所有的答案中都发现,false仅在使用短路和类似x&&y时执行。这被评估为T.false(x)?x:T.&(x,y) 好的,我有下面的代码。struct包含一个int,如果int大于零,则认为自己为真: public struct MyStruct { private int _i; public MyStruct(int i)
false
操作符
有些相同,但接受的答案链接到返回404错误的url。我也看了一些其他的问题
我在几乎所有的答案中都发现,false
仅在使用短路和类似x&&y
时执行。这被评估为T.false(x)?x:T.&(x,y)
好的,我有下面的代码。struct
包含一个int
,如果int大于零,则认为自己为真:
public struct MyStruct {
private int _i;
public MyStruct(int i) {
_i = i;
}
public static bool operator true(MyStruct ms) {
return ms._i > 0;
}
public static bool operator false(MyStruct ms) {
return ms._i <= 0;
}
public override string ToString() {
return this._i.ToString();
}
}
但是,它甚至不编译。它表示不能将运算符“&&”应用于“MyStruct”和“MyStruct”类型的操作数
我知道我可以实现&
操作符的重载。那我们就这么做吧。&
必须返回一个MyStruct
,因此我不能让它返回一个bool
public static MyStruct operator &(MyStruct lhs, MyStruct rhs) {
return new MyStruct(lhs._i & rhs._i);
}
现在代码可以编译了。其输出为1
和-1
。因此,b1&&b2
的结果与b2&&b1
的结果不同
如果我调试代码,我会看到b1&&b2
首先在b1
上执行false
操作符,该操作符返回false
。然后对b1和b2执行&
运算符,对1和-1执行按位and运算,得到1。因此,它确实是第一次检查b1是否为假
第二个表达式,b2&&b1
首先执行b2
上的false
运算符,该运算符返回true
。结合我使用短路的事实,它对b1
没有任何作用,只是打印出b2
的值
因此,当您使用短路时,将执行false
运算符。但是,它不会对第二个参数执行true
或false
运算符,而是对操作数执行重载的&
运算符
这什么时候有用?或者,我如何创建我的类型,以便它可以检查这两个变量是否都为真?编辑-
通过阅读链接文章,我能够获得以下使用true和false运算符的输出:
op false on 1
op & on 1 -1
op true on 1
op true on -1
FALSE
op false on -1
op true on -1
FALSE
op true on 1
op true on 1
TRUE
op true on -1
op & on -1 1
op true on -1
op true on 1
TRUE
使用代码:
class Program
{
static void Main(string[] args)
{
MyStruct b1 = new MyStruct(1); // to be considered true
MyStruct b2 = new MyStruct(-1); // to be considered false
Console.WriteLine((b1 && b2) ? "TRUE" : "FALSE");
Console.WriteLine((b2 && b1) ? "TRUE" : "FALSE");
Console.WriteLine((b1 || b2) ? "TRUE" : "FALSE");
Console.WriteLine((b2 || b1) ? "TRUE" : "FALSE");
Console.ReadLine();
}
}
public struct MyStruct
{
private int _i;
public MyStruct(int i)
{
_i = i;
}
public static bool operator true(MyStruct ms)
{
Console.WriteLine("op true on {0}", ms);
return ms._i > 0;
}
public static bool operator false(MyStruct ms)
{
Console.WriteLine("op false on {0}", ms);
return ms._i <= 0;
}
public static MyStruct operator &(MyStruct lhs, MyStruct rhs)
{
Console.WriteLine("op & on {0} {1}", lhs, rhs);
if (lhs)
{
return rhs;
}
else
{
return new MyStruct(-1); //-1 is false
}
}
public static MyStruct operator |(MyStruct lhs, MyStruct rhs)
{
Console.WriteLine("op & on {0} {1}", lhs, rhs);
if (lhs)
{
return lhs;
}
else
{
return rhs;
}
}
public override string ToString()
{
return this._i.ToString();
}
}
代码:
类程序
{
静态void Main(字符串[]参数)
{
MyStruct b1=新的MyStruct(1);//被认为是真的
MyStruct b2=new MyStruct(-1);//将被视为false
控制台写入线(b1和b2);
控制台写入线(b2和b1);
控制台写入线(b2 | | b1);
控制台写入线(b1 | | b2);
Console.ReadLine();
}
}
公共结构MyStruct
{
私人互联网;;
公共MyStruct(int i)
{
_i=i;
}
公共静态布尔运算符true(MyStruct ms)
{
WriteLine(“op true on{0}”,ms);
返回ms._i>0;
}
公共静态布尔运算符false(MyStruct ms)
{
WriteLine(“在{0}上的op false”,ms);
返回ms._i0;
}
公共重写字符串ToString()
{
将此返回。_i.ToString();
}
}
您提到的404 URL的内容可以在这里找到:
作者所指的文章如下:
为了避免再次出现同样的问题,以下是本文的要点:
几个月前,我发布了关于我们的查询API的文章,并解释了它是如何工作的。我们的查询API允许我们使用强类型C#语法表达查询:
相关的运算符重载如下所示
公共静态布尔运算符true(标准){
返回false;
}
公共静态布尔运算符false(标准){
返回false;
}
公共静态标准运算符&(标准lhs、标准rhs){
返回新的AND标准(左侧、右侧);
}
公共静态标准运算符|(标准lhs、标准rhs){
返回新的OrCriteria(左、右);
}
来自Microsoft(http://msdn.microsoft.com/en-us/library/6292hy1k.aspx):
在C#2.0之前,true和false运算符用于创建用户定义的
与SqlBool等类型兼容的可空值类型。然而,
该语言现在提供了对可空值类型的内置支持,以及
只要有可能,您就应该使用它们,而不是重载true和
假操作员
如果您希望将对象计算为布尔值,请删除运算符true和运算符false重载,然后使用布尔重载。回答您的最后一个问题:“如何创建我的类型,以便它可以检查这两个变量是否都为真?”-只需使用
&
运算符。&&
的全部要点是短路,以便在不需要时不检查第二个参数
看看这个:
Console.WriteLine(b1 & b2); // outputs 1
Console.WriteLine(b2 & b1); // outputs 1
实际上,您缺少了一个重要的部分,它允许您将MyStruct(与&
和|
一起)作为布尔值使用—隐式转换为bool
:
public static implicit operator bool(MyStruct ms) {
return ms._i > 0;
}
这允许您使用MyStruct(以及运算符的结果),如下所示:
作为最后一个,可能是最重要的,请注意:您的示例中的问题来自这样一个事实:您希望执行逻辑操作(检查MyStruct
的两个实例是否为true
),但您的和运算符为此目的实现得不正确。它以二进制算术的方式工作,当使用参数调用MyStruct(1)
(true
)和MyStruct(-1)
(false
)时,会生成值为1
的MyStruct的实例。所以它基本上是这样做的
(true&false)==true
。这就是为什么在您的示例中,b1&&b2
给出了与b2&&b1
不同的结果。基于此运算符的任何其他逻辑
class Program
{
static void Main(string[] args)
{
MyStruct b1 = new MyStruct(1); // to be considered true
MyStruct b2 = new MyStruct(-1); // to be considered false
Console.WriteLine(b1 && b2);
Console.WriteLine(b2 && b1);
Console.WriteLine(b2 || b1);
Console.WriteLine(b1 || b2);
Console.ReadLine();
}
}
public struct MyStruct
{
private int _i;
public MyStruct(int i)
{
_i = i;
}
public static bool operator true(MyStruct ms)
{
Console.WriteLine("op true on {0}", ms);
return ms._i > 0;
}
public static bool operator false(MyStruct ms)
{
Console.WriteLine("op false on {0}", ms);
return ms._i <= 0;
}
public static implicit operator bool(MyStruct ms)
{
Console.WriteLine("op bool on {0}", ms);
return ms._i > 0;
}
public override string ToString()
{
return this._i.ToString();
}
}
List<Customer> customers = repository.FindAll(Customer.Columns.Age == 20 & Customer.Columns.Name == “foo”);
repository.FindAll(Customer.Columns.Age == 20 && Customer.Columns.Name == “foo”);
repository.FindAll(Customer.Columns.FirstName == “Foo” || Customer.Columns.LastName == “Bar”);
public static bool operator true(Criteria<T> criteria) {
return false;
}
public static bool operator false(Criteria<T> criteria) {
return false;
}
public static Criteria<T> operator &(Criteria<T> lhs, Criteria<T> rhs) {
return new AndCriteria<T>(lhs, rhs);
}
public static Criteria<T> operator |(Criteria<T> lhs, Criteria<T> rhs) {
return new OrCriteria<T>(lhs, rhs);
}
Console.WriteLine(b1 & b2); // outputs 1
Console.WriteLine(b2 & b1); // outputs 1
public static implicit operator bool(MyStruct ms) {
return ms._i > 0;
}
if (b1 & b2)
Console.WriteLine("foo");