String s1 = \"Hello\";
String s2 = \"Hello\";
Here s1, s2 are different but then why ReferenceEquals() is returning true
This is due to interning - the CLI automatically re-uses strings obtained as literals (i.e. strings that have come directly from your source code). Note that if you did:
char[] chars = {'h','e','l','l','o'};
string s1 = new string(chars);
string s2 = new string(chars);
they would not be the same string instance, as they have not come from literals.
This is documented against the Ldstr IL instruction:
The Common Language Infrastructure (CLI) guarantees that the result of two ldstr instructions referring to two metadata tokens that have the same sequence of characters return precisely the same string object (a process known as "string interning").