using System;
public class A{
public bool func(){
return true;
}
public int func2(){
return 10;
}
}
public class HelloWorld
{
public static void Main(string[] args)
{
A a = new A();
if(a?.func()){
Console.WriteLine("true"); // Error
}
if(a?.func2() == 10){
Console.WriteLine("true"); // print: True
}
}
}
Like above case, I want to use null conditional operator with A function that returns a bool value.
But, It throws error only when used with bool returning function.
Can I know why it works like that?
Ironically, It works well with the phrase
if(a?.func() == true){
Console.WriteLine("true"); // print: true
}
Please, note that even if func returns bool
a?.func()
returns nullable bool? (true, false and ... null):
a : a?.func()
------------------------------------------
null : null
not null : a.func() # either true or false
So you can put
// if `a` is `null` then `a?.func() is null`
// since `null != true` the condition true if and only if
// `a` is not null and `a.func()` returns true
if (a?.func() == true)
here .net compares T? and T instances (T is bool in our case). It does it as follow
// First compute the expression
bool? result = a?.func()
// Then .net checks if Value is not null
// and if it is the Value equals to required value
if (result.HasValue && result.Value == true) ...
Another way is to use ?? to map null into true or false
// in case of null - when `a` is null - assume false
if (a?.func() ?? false)
The very same logic with
if (a?.func2() == 10)
here a?.func2() returns nullable int? which you compare as == 10, i.e.
if a is not null and a.func2() returns 10 then...
The if statement requires a boolean expression. That is, whatever is inside your parenthesis must resolve to either true or false. When you use the null-conditional operator it says, "give me the bool result of func() unless a is null, then give me null". So by adding the ?. you change your expression to a bool?. But as we established, the if statement requires a bool. if (null) is invalid which is what you get when a is null.
So why does if (a?.func() == true) work? By adding == true, you are now changing your expression back to a bool result type by doing a comparison. When a is null, instead of being
if (null)
you now have
if (null == true)
which is a valid boolean expression that resolves to false. So incidentally, the inverse is also valid if (a?.func() == false).
Public Function DBToID(ByVal strValue As Object) As Integer
If strValue Is DBNull.Value Then Return -1
If strValue = "-1" Then Return -1
Return CInteger(strValue)
End Function
I am trying to convert this code in C# and I did this
public static int DBToID(object strValue)
{
if (object.ReferenceEquals(strValue, DBNull.Value))
return -1;
if (object.ReferenceEquals(strValue,"-1"))
return -1;
return CInteger(strValue.ToString());
}
I just need to know whether I am doing it right or not as before I was doing
public static int DBToID(object strValue)
{
if (object.ReferenceEquals(strValue, DBNull.Value))
return -1;
if (strValue == "-1")
return -1;
return CInteger(strValue.ToString());
}
but it is saying Possible unintended reference comparison it is not giving any error just a green line under strValue=="-1".So please explain that object.referenceequals is correct or not .Thanks in advance
public int DBToID(object strValue)
{
if (strValue == DBNull.Value || Convert.ToString(strValue) == "-1")
return -1;
return Convert.ToInt32(strValue);
}
Try this
In C#, when the first operand of the == operator is cast as a reference-type (without any operator-overloading) then the == operator maps to the Object.ReferenceEquals operation. For the string-equality operation to be performed both operands must be known at compile-time to be String instances.
The most succinct (and safe) conversion would be this:
public Int32 DbToId(Object value) {
Int32 ret;
return value == DBNull.Value ? -1 :
Int32.TryParse( CultureInfo.InvariantCulture, value, out ret ) ? ret :
-1;
}
...which is a shorter form of this:
public Int32 DbToId(Object value) {
if( Object.ReferenceEquals( value, DBNull.Value ) ) return -1;
Int32 ret;
if( Int32.TryParse( CultureInfo.InvariantCulture, value, out ret ) ) return ret;
return -1; // fallback, base-case
}
Generally, try to avoid using VB.NET functions in C# (like CInteger) or the Convert.ToXXX methods as it is not immediately obvious what or how the conversion will work. Also avoid ToString calls with no arguments for the same reason. Prefer TryParse with appropriate IFormatInfo overloads.
When the == operator is used to compare two strings, the Equals method is called, which checks for the equality of the contents of the strings rather than the references themselves. For instance, "hello".Substring(0, 4)=="hell" is true, even though the references on the two sides of the operator are different (they refer to two different string objects, which both contain the same character sequence).
Note that operator overloading only works here if both sides of the operator are string expressions at compile time - operators aren't applied polymorphically. If either side of the operator is of type object as far as the compiler is concerned, the normal == operator will be applied, and simple reference equality will be tested.
Taken from here
The code you've written is not wrong per se. The linked post/snippet should help with any confusion for how strings work. Unless you know what you are doing explicitly, using ReferenceEquals is a bad idea and I would use one of the other by-value check methods.
If you call '.ToString()' on the object, then your second condition should work fine:
public int DBToID(object strValue)
{
if (strValue == DBNull.Value)
return -1;
if (strValue.ToString() == "-1")
return -1;
return System.Convert.ToInt32(strValue);
}
In C# I know you can do things like this:
int number = true ? 1 : 0;
This returns the left or right side depending on if the Boolean is true or not.
But is there a way to do the same thing but instead run a function instead of returning a value? Something like this:
This doesn't work (I get multiple syntax errors)
WPS.EDIT_MODE ? ExecuteEditMode() : ExecutePublicMode();
Thanks.
The conditional operator must return a value. Assuming the functions don't both return a meaningful value for you, you should use an if statement to do that:
if(someCondition)
doA();
else
doB();
Although technically you could use an anonymous function to do this if you really wanted:
int number = someCondition ?
new Func<int>(() => { doA(); return 0; })() :
new Func<int>(() => { doB(); return 1; })();
but that's not suggested; using an if/else is both easier and more readable for that case.
If both functions return an int, yes.
The ternary operator is about returning values. Not returning values doesn't make sense.
The conditional operator (?:) returns one of two values depending on
the value of a Boolean expression.
http://msdn.microsoft.com/en-us/library/ty67wk28(v=vs.80).aspx
I've been searching for actual working code where an overloaded false operator actually gets executed.
This question (What's the false operator in C# good for?) is somewhat the same, but the accepted answer links to an url which is returning a 404 error. I've also looked at How does operator overloading of true and false work? and some other questions.
What I've found in almost all answers is that false only gets executed when you use a short circuited and like x && y. This is evaluated as T.false(x) ? x : T.&(x, y).
Ok, so I have the following code. The struct contains an int and considers itself true if the int is greater than zero.:
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();
}
}
Now I would hope the following program will execute and use the overloaded false operator.
class Program {
private static void Main() {
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);
}
}
However, it does not even compile. It says it cannot apply operator '&&' to operands of type 'MyStruct' and 'MyStruct'.
I know I can implement an overload of the & operator. So let's do that. The & must return a MyStruct, so I can not make it return a bool.
public static MyStruct operator &(MyStruct lhs, MyStruct rhs) {
return new MyStruct(lhs._i & rhs._i);
}
Now the code does compile. Its output is 1 and -1. So the result of b1 && b2 is not the same as that of b2 && b1.
If I debug the code, I see that b1 && b2 first executes the false operator on b1, which returns false. Then it performs the & operator on b1 and b2, which performs a bitwise and on 1 and -1, resulting in 1. So it indeed is first checking if b1 is false.
The second expression, b2 && b1 first executes the false operator on b2, which returns true. Combined with the fact I'm using short circuiting, it doesn't do anything with b1 and just prints out the value of b2.
So yes, the false operator is executed when you use short circuiting. However, it does not execute the true or false operator on the second argument, but instead executes the overloaded & operator on the operands.
When can this ever be useful? Or how can I make my type so that it can check if the two variables both are true?
The contents of the URL you mentioned that was 404 can be found here:
http://web.archive.org/web/20080613013350/http://www.ayende.com/Blog/archive/2006/08/04/7381.aspx
The article that the author is referring to is here:
http://web.archive.org/web/20081120013852/http://steve.emxsoftware.com/NET/Overloading+the++and++operators
To avoid the same issue again, here is the highlights from the article:
A couple months ago I posted about our query API along with an explanation of how it works. Our query API allows us to express our queries using strongly typed C# syntax:
List<Customer> customers = repository.FindAll(Customer.Columns.Age == 20 & Customer.Columns.Name == “foo”);
One of the things I pointed out in my previous posts was that I couldn’t overload the && and || operators directly since the framework doesn’t allow such craziness…at least not directly.
In particular, it is not possible to overload member access, method invocation, or the =, &&, ||, ?:, checked, unchecked, new, typeof, as, and is operators.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/csspec/html/vclrfcsharpspec_7_2_2.asp
Over the last month I’ve done a little investigation on the topic to see if and how I can get && and || to behave the way I want. This evening I came across the Conditional logical operators page on MSDN which gave me the answer I was looking for:
The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Then, if x is definitely false, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
The operation x || y is evaluated as T.true(x) ? x : T.|(x, y), where T.true(x) is an invocation of the operator true declared in T, and T.|(x, y) is an invocation of the selected operator |. In other words, x is first evaluated and operator true is invoked on the result to determine if x is definitely true. Then, if x is definitely true, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator | is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
Since we already have the & and | operators in place it was simply a matter of overloading the true and false operators to both return false. This results in the & and | operators always being called which in turn results in the two criteria objects being turned into an AndCriteria/OrCriteria!
So now we can express our criteria expressions using the && and || syntax we’re accustomed to.
repository.FindAll(Customer.Columns.Age == 20 && Customer.Columns.Name == “foo”);
repository.FindAll(Customer.Columns.FirstName == “Foo” || Customer.Columns.LastName == “Bar”);
The relevant operator overloads are shown below.
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);
}
EDIT-
Reading the linked article I was able to get the following output which uses both the true and false operators:
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
With the code:
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();
}
}
I'm not sure what you mean when you say the first code can't compile, although it doesnt use the operator true/false, I ran the following code in 2010 express and got the output:
op bool on 1
op bool on -1
False
op bool on -1
False
op bool on -1
op bool on 1
True
op bool on 1
True
Code:
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();
}
}
Answering your last question: "how can I make my type so that it can check if the two variables both are true?" - just use the & operator. The whole point of && is to short circuit, so that the second argument isn't checked when not necessary.
Check this out:
Console.WriteLine(b1 & b2); // outputs 1
Console.WriteLine(b2 & b1); // outputs 1
You are actually missing one important bit which will allow you to use MyStruct (with & and |) as a boolean - an implicit cast to bool:
public static implicit operator bool(MyStruct ms) {
return ms._i > 0;
}
This allows you to use MyStruct (so also the result of the operators) as such:
if (b1 & b2)
Console.WriteLine("foo");
As the last, possibly most important, note: the problem in your example comes from the fact that you want to do logical operations (check whether 2 instances of MyStruct are true), but your & operator is implemented incorrectly for such a purpose. It works in terms of binary arithmetic, yielding an instance of MyStruct with value 1 when called with arguments MyStruct(1) (true) and MyStruct(-1) (false). So it basically does (true & false) == true. This is why b1 && b2 gives a different result than b2 && b1 in your example. Any further logic based off of this operator will be broken and unpredictable. Behavior of &&, which is implemented in .NET in terms of false and &, confirms this.
EDIT: you want to be able to use MyStruct as a boolean. You implement operators true and false and expect && and || to work in terms of boolean logic. However, you implement & in terms of binary arithmetics (using & on int fields), which makes this implementation of & not compatible with the boolean logic you expect ((1 & -1) == 1, which means (true & false) == false in your interpretation of MyStruct boolean value). Now, consider that && in general is not a logical operator (it doesn't return a bool) - it is a short circuit implemented as T.false(x) ? x : T.&(x, y). Note that it returns MyStruct in your case, which you just interpret as true or false based on the value of its field. The bottom line: you expect && to do a logical test on both operands, but the .NET implementation of && uses your implementation of &, which is not compatible with the boolean logic you expect.
From Microsoft (http://msdn.microsoft.com/en-us/library/6292hy1k.aspx):
Prior to C# 2.0, the true and false operators were used to create user-defined
nullable value types that were compatible with types such as SqlBool. However,
the language now provides built-in support for nullable value types, and
whenever possible you should use those instead of overloading the true and
false operators.
If you're looking to just evaluate your object to a boolean, remove the operator true and operator false overloads and just use the bool overload.
The point of true/false operators is to provide boolean logic semantics without the need for implicit conversion to bool.
If you allow your type to implicitly cast into bool, the true/false operators are no longer needed. But if you want only explicit conversion, or no conversion, but still want to allow your type as a condition in if or while expresssion, you can use true and false operators.
You can overload operator true and false i looked at examples and found this http://msdn.microsoft.com/en-us/library/aa691312%28v=vs.71%29.aspx
I completely dont understand how they work. I know if i write if(obj) and true returns true then the if is executed. It doesnt matter what false returns. However how does false work? in that doc it is suggected that the && operator uses it. I wrote the code below. I dont know how to get && to compile. || gives me a compile error too. How do i get false to be called? and how do i get the && and || to work?
var ts= new MyTimeSpan();// ts += ts;
if (ts){ Console.WriteLine("Is true"); }
else { Console.WriteLine("not true"); }
//Console.WriteLine(ts && ts ? "Y" : "N");
class MyTimeSpan
{
public static MyTimeSpan operator +(MyTimeSpan t, MyTimeSpan t2) { return new MyTimeSpan(); }
public static bool operator true(MyTimeSpan t) { return true; }
public static bool operator false(MyTimeSpan t) { return false; }
}
The defining property of a short circuiting operator is that it doesn't need to evaluate the right side if the left side already determines the result. For or if the left side is true the result will be true in any case and it's unnecessary to evaluate the right side. For and it's the same except that if the left side is false the result will be false.
You need to overload both | and true to get ||. And & and false to get &&.
a||b corresponds to something like op_true(a)?a:(a|b). So if the true operator returns true it does not need to evaluate the expression of b.
a&&b corresponds to something like op_false(a)?a:(a&b). So if the false operator returns true it does not need to evaluate the expression of b.
Overloading the short circuiting operators is useful when creating a custom boolean type, such as nullable bools(See DBBool)
When overloading the true and false operators they don't just return true and false, they are used to determine if a value of your type is considered to be true or false.
If for example a zero value in your class represents false, then a non-zero value represents true:
public static bool operator true(MyTimeSpan t) { return t.Value != 0; }
public static bool operator false(MyTimeSpan t) { return t.Value == 0; }
As the operators are each others inverse, the compiler doesn't need to use both to determine if a value is true or false. If you write if(obj) the compiler will use the true operator to determine if the value is true.
You will need to override & operator for && and | or ||.
Somthing like this: (Just a dummy code)
public static MyTimeSpan operator &(MyTimeSpan t, MyTimeSpan s) { return t; }
public static MyTimeSpan operator |(MyTimeSpan t, MyTimeSpan s) { return t; }