The Documentation implies that out parameters do not need to be initialized (only declared) before they are sent to the function. However, this code:
class Program
{
static void Main()
{
dynamic p = "";
string s;
if (p != null && T(out s))
System.Console.WriteLine(s);
}
static bool T(out string s)
{
s = "";
return true;
}
}
Gives the build error:
Use of unassigned local variable 's'
only when p is dynamic. If p is typed as string or object, no error is produced.
Method T is required to set the variables before returning, so this error seems like hogwash to me (Note that even with a short-circuting &&, the second statement has to execute in order for the "then" block to execute).
Note: you can also download this repro repo to reproduce.
So, is this a legitimate bug (I'm on C# 7.0)? How should I handle this?
UPDATE: This question was the subject of my blog in November 2018. Thanks for the interesting question!
The documentation implies that out parameters do not need to be initialized (only declared) before they are sent to the method.
That's correct. Moreover, a variable passed to an out parameter is definitely assigned when the call returns, because as you note:
Method T is required to set the variables before returning, so this error seems like hogwash to me
Seems that way, doesn't it? Appearances can be deceiving!
Note that even with a short-circuiting &&, the second expression has to execute in order for the "consequence" block of the if to execute.
That is, surprisingly, false. There is a way for the consequence to execute even if the call to T does not execute. Doing so requires us to seriously abuse the rules of C#, but we can, so let's do it!
Instead of
dynamic p = "";
string s;
if (p != null && T(out s))
System.Console.WriteLine(s);
We'll do
P p = new P();
if (p != null && T())
System.Console.WriteLine("in the consequence");
and give a definition for class P that causes this program to run the consequence but not run the call to T.
The first thing we have to do is turn p != null into a method call instead of a null check, and that method must not return bool:
class P
{
public static C operator ==(P p1, P p2)
{
System.Console.WriteLine("P ==");
return new C();
}
public static C operator !=(P p1, P p2)
{
System.Console.WriteLine("P !=");
return new C();
}
}
We are required to overload both == and != at the same time in C#. Overriding Equals and GetHashCode is a good idea but not a requirement, and nothing in this program is a good idea so we'll skip that.
OK, so we now have if (something_of_type_C && T()), and since C is not bool, we'll need to override the && operator. But C# does not allow you to override the && operator directly. Let's digress a moment and talk about the semantics of &&. For Boolean-returning functions A and B, the semantics of bool result = A() && B(); are:
bool a = A();
bool c;
if (a == false) // interesting operation
c = a;
else
{
bool b = B();
c = a & b; // interesting operation
}
bool r = c;
So we generate three temporaries, a, b, and c, we evaluate the left side A(), we check to see if a is false. If it is, we use its value. If not, we compute B() and then compute a & b.
The only two operations in that workflow that are specific to the type bool are check for falsity and non-short-circuiting &, so *those are the operations that are overloaded in a user-defined &&. C# requires you to overload three operations: user defined &, user defined "am I true?" and user defined "am I false?". (Like == and !=, the last two have to be defined in pairs.)
Now, a sensible person would write operator true and operator false so that they always returned opposites. We are not sensible people today:
class C
{
public static bool operator true(C c)
{
System.Console.WriteLine("C operator true");
return true;
}
public static bool operator false(C c)
{
System.Console.WriteLine("C operator false");
return true; // Oops
}
public static C operator &(C a, C b)
{
System.Console.WriteLine("C operator &");
return a;
}
}
Notice that we also require that user-defined & take two Cs and return a C, which it does.
All right, so, recall we had
if (p != null && T())
and p != null is of type C. So we must now generate this as:
C a = p != null; // Call to P.operator_!=
C c;
bool is_false = a is logically false; // call to C.operator_false
if (is_false)
c = a;
else
{
bool b = T();
c = a & b; // Call to C.operator_&
}
But now we have a problem. operator & takes two Cs and returns a C, but we have a bool returned from T. We need a C. No problem, we'll add an implicit user-defined conversion to C from bool:
public static implicit operator C(bool b)
{
System.Console.WriteLine("C implicit conversion from bool");
return new C();
}
OK, so our logic is now:
C a = p != null; // Call to P.operator_!=
C c;
bool is_false = C.operator_false(a);
if (is_false)
c = a;
else
{
bool t = T();
C b = t; // call to C.operator_implicit_C(bool)
c = a & b; // Call to C.operator_&
}
Remember what we are heading towards here is:
if (c)
System.Console.WriteLine("in the consequence");
How do we compute this? C# reasons that if you have operator true on C then you should be able to use it in an if condition by simply calling operator true. So finishing it off, ultimately we have the semantics:
C a = p != null; // Call to P.operator_!=
C c;
bool is_false = C.operator_false(a);
if (is_false)
c = a;
else
{
bool t = T();
C b = t; // call to C.operator_implicit_C(bool)
c = a & b; // Call to C.operator_&
}
bool is_true = C.operator_true(c);
if (is_true) …
But as we see in this crazy example, we can enter the consequence of the if without calling T no problem provided that operator false and operator true both return true. When we run the program we get:
P !=
C operator false
C operator true
in the consequence
A sensible person would never write code where a C was considered to be both true and false at the same time, but a not-sensible person like me today could, and the compiler knows that because we designed the compiler to be correct regardless of whether the program is sensible.
So that explains why if (p != null && T(out s)) says that s can be unassigned in the consequence. If p is dynamic then the compiler reasons "p might be one of these crazy types at runtime, in which case we are no longer working with bool operands, and therefore s might not be assigned".
The moral of the story is: dynamic makes the compiler extremely conservative about what could happen; it has to assume the worst. In this particular case, it has to assume that p != null might not be a null reference check and might not be bool, and that operator true and operator false might both return true.
So, is this a legitimate bug (I'm on C# 7.0)?
The compiler's analysis is correct -- and believe me, this was not easy logic to write or test.
Your code has the bug; fix it.
How should I handle this?
If you want to do a null reference check against a dynamic, your best bet is: if it hurts when you do that, don't do that.
Cast away the dynamic and get back to object, and then do the reference equality check: if (((object)p) == null && …
Or, another nice solution is to make it extremely explicit:
if (object.ReferenceEquals((object)p, null) && …
Those are my preferred solutions. A worse solution is to break it up:
if (p != null)
if (T(out string s))
consequence
Now there is no operator & called even in the worst case. Note though in this case we can still be in a scenario where p != null is true and p is null, since there is nothing stopping anyone from overloading != to always return true regardless of its operands.
Related
I have a condition in a silverlight application that compares 2 strings, for some reason when I use == it returns false while .Equals() returns true.
Here is the code:
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
// Execute code
}
if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
// Execute code
}
Any reason as to why this is happening?
When == is used on an expression of type object, it'll resolve to System.Object.ReferenceEquals.
Equals is just a virtual method and behaves as such, so the overridden version will be used (which, for string type compares the contents).
When comparing an object reference to a string (even if the object reference refers to a string), the special behavior of the == operator specific to the string class is ignored.
Normally (when not dealing with strings, that is), Equals compares values, while == compares object references.
If two objects you are comparing are referring to the same exact instance of an object, then both will return true, but if one has the same content and came from a different source (is a separate instance with the same data), only Equals will return true. However, as noted in the comments, string is a special case because it overrides the == operator so that when dealing purely with string references (and not object references), only the values are compared even if they are separate instances. The following code illustrates the subtle differences in behaviors:
string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3; // Notice: set to object variable!
Console.WriteLine($"{object.ReferenceEquals(s1, s2)} {s1 == s2} {s1.Equals(s2)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s3)} {s1 == s3} {s1.Equals(s3)}");
Console.WriteLine($"{object.ReferenceEquals(s1, s4)} {s1 == s4} {s1.Equals(s4)}");
The output is:
True True True // s1, s2
False True True // s1, s3
False False True // s1, s4
Summary:
Variables
.ReferenceEquals
==
.Equals
s1, s2
True
True
True
s1, s3
False
True
True
s1, s4
False
False
True
== and .Equals are both dependent upon the behavior defined in the actual type and the actual type at the call site. Both are just methods / operators which can be overridden on any type and given any behavior the author so desires. In my experience, I find it's common for people to implement .Equals on an object but neglect to implement operator ==. This means that .Equals will actually measure the equality of the values while == will measure whether or not they are the same reference.
When I'm working with a new type whose definition is in flux or writing generic algorithms, I find the best practice is the following
If I want to compare references in C#, I use Object.ReferenceEquals directly (not needed in the generic case)
If I want to compare values I use EqualityComparer<T>.Default
In some cases when I feel the usage of == is ambiguous I will explicitly use Object.Reference equals in the code to remove the ambiguity.
Eric Lippert recently did a blog post on the subject of why there are 2 methods of equality in the CLR. It's worth the read
http://blogs.msdn.com/ericlippert/archive/2009/04/09/double-your-dispatch-double-your-fun.aspx
== Operator
If operands are Value Types and their values are equal, it returns true else false.
If operands are Reference Types with exception of string and both refer to the same instance (same object), it returns true else false.
If operands are string type and their values are equal, it returns true else false.
.Equals
If operands are Reference Types, it performs Reference Equality that is if both refer to the same instance (same object), it returns true else false.
If Operands are Value Types then unlike == operator it checks for their type first and if their types are same it performs == operator else it returns false.
As far as I understand it the answer is simple:
== compares object references.
.Equals compares object content.
String datatypes always act like content comparison.
I hope I'm correct and that it answered your question.
Firstly, there is a difference. For numbers
> 2 == 2.0
True
> 2.Equals(2.0)
False
And for strings
> string x = null;
> x == null
True
> x.Equals(null)
NullReferenceException
In both cases, == behaves more usefully than .Equals
I would add that if you cast your object to a string then it will work correctly. This is why the compiler will give you a warning saying:
Possible unintended reference comparison; to get a value comparison,
cast the left hand side to type 'string'
Because the static version of the .Equal method was not mentioned so far, I would like to add this here to summarize and to compare the 3 variations.
MyString.Equals("Somestring")) //Method 1
MyString == "Somestring" //Method 2
String.Equals("Somestring", MyString); //Method 3 (static String.Equals method) - better
where MyString is a variable that comes from somewhere else in the code.
Background info and to summerize:
In Java using == to compare strings should not be used. I mention this in case you need to use both languages and also
to let you know that using == can also be replaced with something better in C#.
In C# there's no practical difference for comparing strings using Method 1 or Method 2 as long as both are of type string. However, if one is null, one is of another type (like an integer), or one represents an object that has a different reference, then, as the initial question shows, you may experience that comparing the content for equality may not return what you expect.
Suggested solution:
Because using == is not exactly the same as using .Equals when comparing things, you can use the static String.Equals method instead. This way, if the two sides are not the same type you will still compare the content and if one is null, you will avoid the exception.
bool areEqual = String.Equals("Somestring", MyString);
It is a little more to write, but in my opinion, safer to use.
Here is some info copied from Microsoft:
public static bool Equals (string a, string b);
Parameters
a String
The first string to compare, or null.
b String
The second string to compare, or null.
Returns Boolean
true if the value of a is the same as the value of b; otherwise, false. If both a and b are null, the method returns true.
Just as an addition to the already good answers: This behaviour is NOT limited to Strings or comparing different numbertypes. Even if both elements are of type object of the same underlying type. "==" won't work.
The following screenshot shows the results of comparing two object {int} - values
I am a bit confused here. If the runtime type of Content is of type string, then both == and Equals should return true. However, since this does not appear to be the case, then runtime type of Content is not string and calling Equals on it is doing a referential equality and this explains why Equals("Energy Attack") fails. However, in the second case, the decision as to which overloaded == static operator should be called is made at compile time and this decision appears to be ==(string,string). this suggests to me that Content provides an implicit conversion to string.
There is another dimension to an earlier answer by #BlueMonkMN. The additional dimension is that the answer to the #Drahcir's title question as it is stated also depends on how we arrived at the string value. To illustrate:
string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("\n Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));
Console.WriteLine("\n Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));
The output is:
True True True
Case1 - A method changes the value:
False True True
False False True
Case2 - Having only literals allows to arrive at a literal:
True True True
True True True
Adding one more point to the answer.
.EqualsTo() method gives you provision to compare against culture and case sensitive.
Really great answers and examples!
I would just like to add the fundamental difference between the two,
Operators such as == are not polymorphic, while Equals is
With that concept in mind, if you work out any example (by looking at left hand and right hand reference type, and checking/knowing if the type actually has == operator overloaded and Equals being overriden) you are certain to get the right answer.
This is due to value equality (equal method) and referential equality(== operator), as the equal method checks the values while the same == is checked the reference.
== operator overriding code available inside the string class on https://referencesource.microsoft.com/
so now it's easier to understand, the equal method also has 2 implementations one from the string class itself and one from the object class. its impact on performance as well I also run some basic code and try to understand the benchmarks.
I am sharing the results below Please correct or advise if I am wrong somewhere. there are 3 cases and I have run the same code for all the cases and this is the result.
case 1: here I am using string. equal method for comparing 2 strings and both the string have the same values. string.equals(a,b)
1st run:5608195 ticks
2nd run:5529387 ticks
3rd run:5622569 ticks
total ticks: 16760151
case 2: here I am using string. equal() method(overloaded one) for comparing 2 strings and both the string have the same values.
a.equals(b)
1st run: 6738583 ticks
2nd run: 6452927 ticks
3rd run: 7168897 ticks
total ticks=20360407
case 3: here I am using the == operator for comparing 2 strings and both the string have the same values.
a==b
1st run: 6652151 ticks
2nd run: 7514300 ticks
3rd run: 7634606 ticks
total ticks=21801057
class Program
{
private static int count;
static string a = "abcdef";
static string b = "abcdef";
static void Main(string[] args)
{
for (int j = 1; j <= 3; j++)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 1; i <= 1000; i++)
{
checkString();
}
sw.Stop();
Console.WriteLine(sw.ElapsedTicks);
}
Console.ReadLine();
}
public static void checkString()
{
for (int i = 1; i <= 100000; i++)
{
if (a==b)
count++;
}
}
}
The == token in C# is used for two different equality-check operators. When the compiler encounters that token, it will check whether either of the types being compared has implemented an equality-operator overload for either the specific combination types being compared(*), or for a combination of types to which both types can be converted. If the compiler finds such an overload it will use it. Otherwise, if the two types are both reference types and they are not unrelated classes (either may be an interface, or they may be related classes), the compiler will regard == as a reference-comparison operator. If neither condition applies, compilation will fail.
Note that some other languages use separate tokens for the two equality-check operators. In VB.NET, for example, the = token is used within expressions solely for the overloadable equality-check operator, and Is is used as a reference-test or null-test operator. An to use = on a type which does not override the equality-check operator will fail, as will attempting to use Is for any purpose other than testing reference equality or nullity.
(*)Types generally only overload equality for comparison with themselves, but it may be useful for types to overload the equality operator for comparison with other particular types; for example, int could have (and IMHO should have but didn't) defined an equality operators for comparison with float, so that 16777217 would not report itself equal to 16777216f. As it is, since no such operator is defined, C# will promote the int to float, rounding it to 16777216f before the equality-check operator sees it; that operator then sees two equal floating-point numbers and reports them as equal, unaware of the rounding that took place.
Note that there are two different types of equality in C#
1- Value Equality (For value types like int, DateTime and struct)
2- Reference Equality (For objects)
There are two basic standard protocols for implement equality checks.
1- The == and != operators.
2- The virtual Equals method.
The == and != are statically resolve, which means C# will make a compile-time decision as to which type will perform the comparison.
For instance the value-type
int x = 50;
int y = 50;
Console.WriteLine (x == y); // True
but for reference type
object x = 50;
object y = 50;
Console.WriteLine (x == y); // False
The Equals() originally resoled at runtime according to operand actual type.
For instance, in the following example, at runtime, it will be decided that the Equals() will apply on int values, the result is true.
object x = 5;
object y = 5;
Console.WriteLine (x.Equals (y)); // True
However, for a reference type, it will use a reference equality check.
MyObject x = new MyObject();
MyObject y = x;
Console.WriteLine (x.Equals (y)); // True
Note that Equals() uses structural comparison for struct, which means it calls Equals on each field of a struct.
Whether Equals() and == are the same depends on the implementation. Because C# allows users to set different behaviors for Equals() and == respectively.
class CompareTest
{
public readonly int val;
public CompareTest(int val)
{
this.val = val;
}
public override bool Equals(object obj)
{
return obj is CompareTest test && this.val == test.val;
}
public override int GetHashCode()
{
return val;
}
public static bool operator == (CompareTest a, object b)
{
return Equals(a, b);
}
public static bool operator != (CompareTest a, object b)
{
return !(a == b);
}
}
In this example, I made Equals() and == have the same behavior. But what if I make them different? For example:
public static bool operator == (CompareTest a, object b)
{
return false;
}
Equals() works normally but == will never works.
Furthermore, although I made them have the same behavior, but there is still one difference: which == function will be called depends on the left value:
Compare Test a = new CompareTest(1);
object b = new CompareTest(1);
CompareTest c = new CompareTest(1);
Debug.Log("AB " + (a == b)); // true
Debug.Log("BA " + (b == a)); // false! because it calls object's == function
Debug.Log("AC " + (a == c)); // true
Debug.Log("CA " + (c == a)); // true
When we create any object there are two parts to the object one is the content and the other is reference to that content.
== compares both content and reference;
equals() compares only content
http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq
==
The == operator can be used to compare two variables of any kind, and it simply compares the bits.
int a = 3;
byte b = 3;
if (a == b) { // true }
Note : there are more zeroes on the left side of the int but we don't care about that here.
int a (00000011) == byte b (00000011)
Remember == operator cares only about the pattern of the bits in the variable.
Use == If two references (primitives) refers to the same object on the heap.
Rules are same whether the variable is a reference or primitive.
Foo a = new Foo();
Foo b = new Foo();
Foo c = a;
if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }
a == c is true
a == b is false
the bit pattern are the same for a and c, so they are equal using ==.
Equal():
Use the equals() method to see if two different objects are equal.
Such as two different String objects that both represent the characters in "Jane"
The only difference between Equal and == is on object type comparison. in other cases, such as reference types and value types, they are almost the same(either both are bit-wise equality or both are reference equality).
object:
Equals: bit-wise equality
==: reference equality
string: (equals and == are the same for string, but if one of string changed to object, then comparison result will be different)
Equals: bit-wise equality
== : bit-wise equality
See here for more explanation.
This pattern comes up very frequently in my code:
x= x== 0? 1: x;
//or
x= x==null? 1: x;
However it happens that sometimes x is a long expression and I'd have to use intermediate variables. That's just useless boilerplate code. I can cook up a method and call it instead:
Util.IfNullOrZero(x, 1);
But that's just ugly. What is the best way of expressing the pattern? In ruby there is such syntax for when x is nil which gets rid of redundant x's:
x||= 1
I could extend object in a manner
public static class wtf
{
public static T Default<T>(this object o, T d)
{
return o == null ? d : new object[] { o }.Cast<T>().First();
}
}
And then do
object param= null;
int x= param.Default(1);
But that's a bit expensive.
In short how to best make C# do x||= 1 like in ruby?
Update
This is what I cooked up. I'm currently looking for a faster way of using the Template parameter to convert object to T.
public static class MyExtensions
{
public static T d<T>(this object o, T d)
{
return o == null || o.Equals(default(T)) ? d : new object[] { o }.Cast<T>().First();
}
}
In fact the code does three things at once: Casts to default type, checks for default value and also checks for null.
Update 2
return o == null || o.Equals(default(T)) ? d : (T)o; // much simpler and faster
I still think it is a commonality which needs to be included in core language.
Update 3
This is what I finally wrote, taking into account DataTable DBNull types.
public static T d<T>(this object o, T d)
{
return o == null || (o is System.DBNull) || o.Equals(default(T)) ? d : (T)Convert.ChangeType(o, typeof(T));
}
For handling the "==null" case, the null coalesce operator does the trick.
y = x ?? z;
means
if (x == null)
y = z;
else
y = x;
I'm not aware of something that check for both zero and null, writing a method to perform this task might be the best solution. Here it goes:
public static T IsNullOrZero<T>(this T variable, T defaultValue)
{
// defaultValue can't be null, doesn't make sense
if (defaultValue == null) throw new ArgumentException("default value can't be null", "defaultValue");
if (variable == null || variable.Equals(default(T)))
return defaultValue;
return variable;
}
Usage:
x = x.IsNullOrZero(y);
Note: this in fact works on non-numbers too (name might be misleading if dealing with non-numbers... maybe something along the lines of IsNullOrDefault might be a better name).
You can check like
public static bool IsNullOrValue(this int? value, int valueToCheck)
{
return (value??valueToCheck) == valueToCheck;
}
more on here
For checking for null and providing a default value, you can use the ?? operator:
return x ?? new Foo();
That means, if x is null, return new Foo(), else return x. You can use it for reference types and nullable types. For nun-nullable types like int, you still need to explicitly check for 0.
What you want is the Coalesce operator (??), which does just that - if returns the first operand if it's not null, and the second if it is. This will instantiate a new object if the current one is null:
return myObj ?? new MyObject();
Note that the ?? operator works only for classes and reference types, not for ints and other value types that can't be null. There, you'll have to check manually for default, uninitialized values (0 for ints and shorts and stuff, false for bools, and so forth)
Suppose you are using the ternary operator, or the null coalescing operator, or nested if-else statements to choose assignment to an object. Now suppose that within the conditional statement, you have the evaluation of an expensive or volatile operation, requiring that you put the result into a temporary variable, capturing its state, so that it can be compared, and then potentially assigned.
How would a language, such as C#, for consideration, implement a new logic operator to handle this case? Should it? Are there existing ways to handle this case in C#? Other languages?
Some cases of reducing the verbosity of a ternary or null coalescing operator have been overcome, when we assume that we are looking for direct comparisons, for example. See Unique ways to use the Null Coalescing operator, in particular the discussion around how one can extend the usage of the operator to support String.IsNullOrEmpty(string). Note how Jon Skeet is using the PartialComparer from MiscUtil, to reformat 0s to nulls,
Why is this possibly necessary? Well, take a look at how we write a comparison method for complex objects without any shortcuts (examples from the cited discussions):
public static int Compare( Person p1, Person p2 )
{
return ( (result = Compare( p1.Age, p2.Age )) != 0 ) ? result
: ( (result = Compare( p1.Name, p2.Name )) != 0 ) ? result
: Compare( p1.Salary, p2.Salary );
}
Jon Skeet writes a new comparison to fallback the equality case. This allows the expression to extend by writing a new specific method which returns null, allowing us to use the null coalescing operator:
return PartialComparer.Compare(p1.Age, p2.Age)
?? PartialComparer.Compare(p1.Name, p2.Name)
?? PartialComparer.Compare(p1.Salary, p2.Salary)
?? 0;
The null coalescing operator is more readable because it has two sides, not three. The boolean condition clause is separated into a method, in this case returning null if the expression must be continued.
What would the above expression look like if we could more easily put the condition in-line? Take the expression from PartialComparer.Compare which returns null, and place it in a new ternary expression which allows us to use the evaluation of the left-side expression, with an implicit temporary variable value:
return Compare( p1.Age, p2.Age ) unless value == 0
: Compare( p1.Name, p2.Name ) unless value == 0
: Compare( p1.Salary, p2.Salary );
The basic "flow" of an expression would be:
expression A unless boolean B in which case expression C
Rather than being an overloaded comparison operator, I suppose this is more like a short-circuiting inverted ternary operator.
Would this type of logic be useful? Currently the null coalescing provides us a way to do this with the conditional expression (value == null).
What other expressions would you want to test against? We've heard of (String.IsNullOrEmpty(value)).
What would be the best way to express this in the language, in terms of operators, keywords?
personally I'd avoid the short circuit from operators and just let the methods chain it:
public static int CompareChain<T>(this int previous, T a, T b)
{
if (previous != 0)
return previous;
return Comparer<T>.Default.Compare(a,b);
}
use like so:
int a = 0, b = 2;
string x = "foo", y = "bar";
return a.Compare(b).CompareChain(x,y);
can be inlined by the JIT so it can perform just as well as short circuiting built into the language without messing about with more complexity.
In response to your asking whether the above 'structure' can apply to more than just comparisons then yes it can, by making the choice of whether to continue or not explict and controllable by the user. This is inherently more complex but, the operation is more flexible so this is unavoidable.
public static T ElseIf<T>(
this T previous,
Func<T,bool> isOK
Func<T> candidate)
{
if (previous != null && isOK(previous))
return previous;
return candidate();
}
then use like so
Connection bestConnection = server1.GetConnection()
.ElseIf(IsOk, server2.GetConnection)
.ElseIf(IsOk, server3.GetConnection)
.ElseIf(IsOk, () => null);
This is maximum flexibility in that you can alter the IsOk check at any stage and are entirely lazy. For situations where the is OK check is the same in every case you can simplify like so and entirely avoid extensions methods.
public static T ElseIf<T>(
Func<T,bool> isOK
IEnumerable<Func<T>[] candidates)
{
foreach (var candidate in candidates)
{
var t = candidate();
if (isOK(t))
return t;
}
throw new ArgumentException("none were acceptable");
}
You could do this with linq but this way gives a nice error message and allows this
public static T ElseIf<T>(
Func<T,bool> isOK
params Func<T>[] candidates)
{
return ElseIf<T>(isOK, (IEnumerable<Func<T>>)candidates);
}
style which leads to nice readable code like so:
var bestConnection = ElseIf(IsOk,
server1.GetConnection,
server2.GetConnection,
server3.GetConnection);
If you want to allow a default value then:
public static T ElseIfOrDefault<T>(
Func<T,bool> isOK
IEnumerable<Func<T>>[] candidates)
{
foreach (var candidate in candidates)
{
var t = candidate();
if (isOK(t))
return t;
}
return default(T);
}
Obviously all the above can very easily be written using lambdas so your specific example would be:
var bestConnection = ElseIfOrDefault(
c => c != null && !(c.IsBusy || c.IsFull),
server1.GetConnection,
server2.GetConnection,
server3.GetConnection);
You've got lots of good answers to this question already, and I am late to this particular party. However I think it is worthwhile to note that your proposal is a special case of a more generally useful operation which I dearly wish C# had, namely, the ability to in an expression context, give a name to a temporary computation.
In fact C# has this operator but only in query comprehensions. I wish we had been able to add this as an operator in C# 3:
public static int Compare(Person p1, Person p2) =>
let ages = Compare(p1.Age, p2.Age) in
ages != 0 ?
ages :
let names = Compare(p1.Name, p2.Name) in
names != 0 ?
names :
Compare(p1.Salary, p2.Salary);
"Let expressions" are one of those expressions that are so useful, and found in so few languages, and I genuinely do not understand why language designers do not add it immediately in version one.
If C# had this feature then your proposed:
A() unless B() : C()
is simply
let a = A() in B() ? C() : a
which is hardly more difficult to understand, and bonus, you get to use a in expressions B() and C() if you like.
Let expressions can be emulated in any language that has lambdas; of course let x = y in z is simply (x=>z)(y), but there is no concise way to write that in C# either because C# requires a conversion to a delegate type on every lambda.
Incidentally, in Roslyn we do not represent temporaries as let-expressions, though we could. Rather, we go even one level below that and have a representation for "sequence of operations that might produce values, one of which will become the value of this expression". "let x = y in z" is simply the sequence "allocate x, x = y, z, deallocate x" where the third element is the value. And in the original pre-roslyn C# compiler we had internal operators "left" and "right", which were binary operators that took two expressions and produced either the left or right side, so we could generate ((allocate x) right ((x = y) right z)) left (deallocate x).
My point here is: we often get requests for bespoke language features with unusual punctuation, but it would in general have been better to implement the basic building blocks that you could build these operators out of in a natural way.
To place one proposed implementation away from a very verbose question, let's run with the unless keyword.
(expression A) unless (boolean B) <magical "in which case" operator> (expression C)
... would be all there is to it.
Boolean expression B would have access to the evaluation of expression A through the keyword value. Expression C could have the unless keyword in its expression, allowing for simple, linear chaining.
Candidates for the <magical "in which case" operator>:
:
|
?:
otherwise keyword
Usage of any symbols tend to diminish readability for the average developer. Even the ?? operator is not used widely. I, myself, do prefer to develop verbose code, but that I can easily read one year from now.
So a candidate for your :
expression A unless boolean B in which case expression C.
would be
expression A unless boolean B sothen expression C.
Although many people like me would still use:
if (B) {expression C;}
else {expression A;}
This comes in when you are developing a software with a big team, with different backgrounds, each one on the team master of one language, and just user of others.
More #ShuggyCoUk: Ah, I see that this might work for more than just comparisons? I haven't used C# 3 and extension methods, but I suppose you can declare, for my previous example, below, a
public delegate bool Validation<T>( T toTest );
public static T Validate<T>( this T leftside, Validation<T> validator )
{
return validator(leftside) ? leftside : null;
}
Followed by, per Skeet:
Validation<Connection> v = ( Connection c ) => ( c != null && !( c.IsBusy || c. IsFull ) );
Connection bestConnection =
server1.GetConnection().Validate( v ) ??
server2.GetConnection().Validate( v ) ??
server3.GetConnection().Validate( v ) ?? null;
Is this how that would work in C#? Comments appreciated. Thank you.
In response to ShuggyCoUk:
So this is an extension method in C# 3, then? Also, the result here is an int, not an arbitrary expression. Useful for overloading yet another comparison method. Suppose I wanted an expression for choosing the best connection. Ideally, I want something to simplify the following:
Connection temp;
Connection bestConnection =
( temp = server1.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull) ? temp
: ( temp = server2.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull ) ? temp
: ( temp = server3.GetConnection() ) != null && !(temp.IsBusy || temp.IsFull ) ? temp
: null;
Ok, so one could have a method
bool IsOk( Connection c )
{
return ( c != null && !(c.IsBusy || c.IsFull) );
}
Which would produce:
Connection temp;
Connection bestConnection =
( temp = server1.GetConnection() ) && IsOk( temp ) ? temp
: ( temp = server2.GetConnection() ) && IsOk( temp ) ? temp
: ( temp = server3.GetConnection() ) && IsOk( temp ) ? temp
: null;
But how would method chaining for comparisons work, here? I am pondering something which looks like:
Connection bestConnection =
server1.GetConnection() unless !IsOk(value) otherwise
server2.GetConnection() unless !IsOk(value) otherwise
server3.GetConnection() unless !IsOk(value) otherwise null;
I think that there are so far, hoops to jump through, if I want the result of a conditional to be an expression or result of a method which was in the original conditional.
I assume that the object returned by such methods will be expensive to produce, or will change the next time the method is called.
This question already has answers here:
Closed 13 years ago.
Just I would like to know, is there any difference between
if (a==5) or if (5==a)
in C#, Which one is better?
There's no difference - assuming that "a" is an integer.
I know some people prefer if (5==a) because in c & c++ if you wrote if (5=a) by mistake you'd get a compiler error while if (a=5) would result in a bug.
C# raises a compiler error in the latter case, so it's not an issue.
I'd actually say there is a difference, but it's not a technical one (as everyone has well covered already) - readability. It matters and the first form is much more natural.
The if(5 == a) construct is common in C/C++ because boolean values are represented using ints. Thus if you write a = 5 by mistake this can be evaluated in the context of the if, which is most likely not what you wanted.
In C# there's no implicit conversion from int to bool, so if you type = instead of == you'll get a compile error.
no difference, it is an old habit to avoid if(a=5) in c/c++.
These questions/answers are about the same:
(0 == variable) or (null == obj): An outdated practice in C#?
Checking for null, which is better? "null ==" or "==null"
Why does one often see "null != variable" instead of "variable != null" in C#?
Both are equivalent.
I remember when I used to code in C, I preferred 'if (5==a)' because it guarantees that I haven't typed 5=a accidentally as the compiler would throw error. This would not happen if we write 'if (a=5)'. Though it is a typo, it would not generate any compiler error and would go unnoticed.
But, in C# it is not the case. There is no logical reason to write 'if (5==a)'. If we had written 'if(a=5)', the compiler would throw an error. So in C# use 'if(a==5)'!
With correct design, there is no difference between "a == 5" and "5 == a". But there is some special situation, where has "a == 5" and "5 == a" different behaviour. It's very unpropably, but it is posible.
Nevertheless this example is constructed for demonstration of the situation, and I does not recomend do thinks such this.
Example:
public class BadClass {
public int Value;
public static implicit operator int( BadClass c ) {
return c.Value;
}
//public static implicit operator BadClass( int n ) {
// return new BadClass { Value = n };
//}
public static bool operator ==( BadClass c, int n ) {
return (c.Value + 1 == n);
}
public static bool operator !=( BadClass c, int n ) {
return (c.Value + 1 != n);
}
public override bool Equals( object obj ) {
if ( obj is int ) {
return (this == (int)obj);
}
else {
return base.Equals( obj );
}
}
public override int GetHashCode() {
return base.GetHashCode();
}
}
...
BadClass a = new BadClass { Value = 13 };
var rslt_1 = (13 == a); //there will be true
var rslt_2 = (a == 13); //there will be false
Other than the safety if (5==a) gives you, No.
Only difference is if you forget the second equals, the first version is still a valid statement whereas the second version will raise a compile time error.
HTH
cheers,
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I check for nulls in an '==' operator overload without infinite recursion?
When I overload the == operator for objects I typically write something like this:
public static bool operator ==(MyObject uq1, MyObject uq2) {
if (((object)uq1 == null) || ((object)uq2 == null)) return false;
return uq1.Field1 == uq2.Field1 && uq1.Field2 == uq2.Field2;
}
If you don't down-cast to object the function recurses into itself but I have to wonder if there isn't a better way?
As Microsoft says,
A common error in overloads of
operator == is to use (a == b), (a ==
null), or (b == null) to check for
reference equality. This instead
results in a call to the overloaded
operator ==, causing an infinite loop.
Use ReferenceEquals or cast the type
to Object, to avoid the loop.
So use ReferenceEquals(a, null) || ReferenceEquals(b, null) is one possibility, but casting to object is just as good (is actually equivalent, I believe).
So yes, it seems there should be a better way, but the method you use is the one recommended.
However, as has been pointed out, you really SHOULD override Equals as well when overriding ==. With LINQ providers being written in different languages and doing expression resolution at runtime, who knows when you'll be bit by not doing it even if you own all the code yourself.
ReferenceEquals(object obj1, object obj2)
#neouser99: That's the right solution, however the part that is missed is that when overriding the equality operator (the operator ==) you should also override the Equals function and simply make the operator call the function. Not all .NET languages support operator overloading, hence the reason for overriding the Equals function.
if ((object)uq1 == null)
return ((object)uq2 == null)
else if ((object)uq2 == null)
return false;
else
//return normal comparison
This compares them as equal when both are null.
Just use Resharper to create you Equals & GetHashCode methods. It creates the most comprehensive code for this purpose.
Update
I didn't post it on purpose - I prefer people to use Resharper's function instead of copy-pasting, because the code changes from class to class. As for developing C# without Resharper - I don't understand how you live, man.
Anyway, here is the code for a simple class (Generated by Resharper 3.0, the older version - I have 4.0 at work, I don't currently remember if it creates identical code)
public class Foo : IEquatable<Foo>
{
public static bool operator !=(Foo foo1, Foo foo2)
{
return !Equals(foo1, foo2);
}
public static bool operator ==(Foo foo1, Foo foo2)
{
return Equals(foo1, foo2);
}
public bool Equals(Foo foo)
{
if (foo == null) return false;
return y == foo.y && x == foo.x;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
return Equals(obj as Foo);
}
public override int GetHashCode()
{
return y + 29*x;
}
private int y;
private int x;
}
But why don't you create an object member function? It can certainly not be called on a Null reference, so you're sure the first argument is not Null.
Indeed, you lose the symmetricity of a binary operator, but still...
(note on Purfideas' answer: Null might equal Null if needed as a sentinel value of an array)
Also think of the semantics of your == function: sometimes you really want to be able to choose whether you test for
Identity (points to same object)
Value Equality
Equivalence ( e.g. 1.000001 is equivalent to .9999999 )
Follow the DB treatment:
null == <anything> is always false