Here are the links to previous articles:
  I am here to continue my series related to .NET interview preparation. Today, we  will discuss the questions related to equality and go through the answers in an easy way.
 
 So let’s take questions one by one.
 
 Question: How does equality operator == work with value and reference  types? Explain with example.
 
 Answer:
 
 == is the comparison operator that compares reference identity of reference  types (except string) and data of value types. For string type, it always checks  the content.
 
 Compiler overloads == is based on the compile time type of the operands. For  example if == is used in object type operands, it will resolve to  System.Object.ReferenceEqualsin runtime.
 
 Example:
 
-   
- Console.WriteLine("-------------------Value Types and string:-------------------");  
- Console.WriteLine("Compare {0} and {1}: {2}", 2, 2, 2 == 2);   
- Console.WriteLine("Compare {0} and 2.0: {1}", 2, 2 == 2.0);   
- Console.WriteLine("Compare {0} and {1}: {2}", 2, 3, 2 == 3);   
- Console.WriteLine("Compare {0} and {1}: {2}", "prakash", "prakash", "prakash" == "prakash");   
- Console.WriteLine("Compare {0} and {1}: {2}", "prakash", "prakash", "prakash" == newstring("prakash".ToCharArray()));   
- Console.WriteLine("Compare {0} and {1}: {2}", "prakash", "tripathi", "prakash" == "tripathi");   
-   
-   
- Console.WriteLine("\n-------------------Reference Types:-------------------");  
- objectobj1 = "prakash";  
- objectobj2 = newstring("prakash".ToCharArray());  
- Console.WriteLine("Compare {0} and {1}: {2}", obj1, obj2, obj1 == obj2);   
![see output]() 
  As you can see that for value types and string, == has usesdoverloaded version (int.operator,  double.operator and string.operator) and compared the data or content whereas  for reference type (i.e. object) it has used object.operator and compared the  reference.  
Question: What is Equals method and how is it  different from ==? Explain  with example. 
 Answer
  Equalsis  used to compare the data equality for instances of the same type unlike ==  which checks the references (of reference types). Equals is a virtual method and  resolves at runtime (unlike ==).  
 For string types, Equals use its string overload to compare the content of the  string. Additionally, if any object type gets resolved as string at runtime then  it compares the string content instead of reference.  
The following example clearly illustrates the difference of == and Equals where for  two object type variables (obj1, obj2), both are used. 
- object obj1 = "prakash";  
- object obj2 = newstring("prakash".ToCharArray());  
- Console.WriteLine("Compare {0} and {1}: {2}", obj1, obj2, obj1 == obj2);   
- Console.WriteLine("Compare {0} and {1}: {2}", obj1, obj2, obj1.Equals(obj2));   
![see result]() 
  As you can see that == compared the references of obj1 and obj2 whereas Equals  just checked the data or content.  
Question: What’s the ReferenceEquals method and how is it different from  == and Equals?  
Answer
  ReferenceEquals is a static method that checks if the two objects are of same  instance or not unlike Equals that checks the data equality and == which behaves  differently for value and reference types. 
 For value type comparisons, ReferenceEquals always returns false because before  checking, it boxes the values and due to that a different object instance gets  created. For immutable types such as string, ReferenceEquals works in following  way- 
 	- If string content is same and interned (If you don’t know about string  	interning, follow Que. 4 below) in two string instances, ReferenceEquals  	returns true.
 
 
- If string is not interned, ReferenceEquals will return false despite whether the  	content is matching.
Example:
 
- Console.WriteLine("-------------------Value Types and string:-------------------");  
- Console.WriteLine("Compare {0} and {1} using ReferenceEquals: {2}", 2, 2, object.ReferenceEquals(2, 2));   
- stringname1 = "prakash";  
- stringname2 = "prakash";  
- stringname3 = newstring("prakash".ToCharArray());  
- Console.WriteLine("Compare {0} and {1} using ReferenceEquals: {2}", name1, name2, object.ReferenceEquals(name1, name2));   
- Console.WriteLine("Compare {0} and {1} using ReferenceEquals: {2}", name1, name3, object.ReferenceEquals(name1, name3));   
-   
- Console.WriteLine("\n-------------------Reference Types:-------------------");  
- objectobj1 = "prakash";  
- objectobj2 = newstring("prakash".ToCharArray());  
- objectobj3 = obj1;  
- Console.WriteLine("Compare {0} and {1} using ReferenceEquals: {2}", obj1, obj2, object.ReferenceEquals(obj1, obj2));   
- Console.WriteLine("Compare {0} and {1} using ReferenceEquals: {2}", obj1, obj3, object.ReferenceEquals(obj1, obj3));   
![Output]() 
  As you can see for value types and non-interned strings, ReferenceEquals  always returns false and for reference types, instance is compared.  
Question: What’s the string interning and when it can be used?  
Answer
  String interning is low level string pool optimization and can speed up  performance when dealing with lot of string comparisons. Any string is called  interned if it's present in shared or common string pool also called Interned  pool.  
 When we create string literals, they by default go into intern table or pool.  Typically comparisons between two interned or literal strings are faster than a  comparison between interned and dynamically built strings. 
 String becomes non-interned when we do some sort of manipulation on top of  literals however a method (Intern) is provided by .NET Framework to enforce  interning manually. Manual interning puts the dynamically built string into  intern table and gives the same optimization as literals. 
 There is one more method (IsInterned) available to check if string is interned  or not.  
Example:
 - string str1 = "prakash";  
- string str2 = "Hello! ";  
- string str3 = str2 + "prakash";   
- Console.WriteLine("Is {0} Interned? {1}", str1, string.IsNullOrEmpty(string.IsInterned(str1)) ? "NO" :"YES");  
- Console.WriteLine("Is {0} Interned? {1}", str3, string.IsNullOrEmpty(string.IsInterned(str3)) ? "NO" : "YES");  
![run]() 
  As you can see that string literal str1 is interned however dynamically added  str3 is not. Also before using Intern in real world applications, have a  benchmarking done to know if it’s really giving any significant performance  benefit as it may be only useful when dealing with a big load or thousands of  string comparisons.  
Question: What’s the output of the following program? 
- Console.WriteLine("{0}", 3.Equals(3.0));  
- Console.WriteLine("{0}", object.ReferenceEquals(3, 3.0));  
  False//integer and double comparison 
False// ReferenceEquals always returns false for value types  
Question: What’s the output of the following program? 
- string str = null;  
- Console.WriteLine("{0}", str == null);  
- Console.WriteLine("{0}", str.Equals(null));  
- Console.WriteLine("{0}", object.ReferenceEquals(str, null));  
  True//Null comparison is supported 
NullReferenceException // Equals doesn’t support null  
True//Null comparison is supported 
 Hope you have liked the article. Look forward for your comments/suggestions.
 
Read more articles on .NET Core: