When you initialized
object x = "mehdi emrani"; //pointer(x)
It initialized it in memory and assign reference to x. After this when you initialized
string y = "mehdi emrani"; //pointer(x)

compiler find that this value is already in memory so it assign same reference to y.
Now ==
equal operator which actually compares the addresses instead of value find the same address for both variable which results true:
x==y //actually compares pointer(x)==pointer(x) which is true
In second case when you initialized x and y that get assigned different addresses.
object x = "mehdi emrani"; //Pointer(x)
string y = "mehdi "; //not found in memory
y += "emrani"; //Pointer(y)
Now comparison find different addresses which results false:
x == y //is actually Pointer(x) == Pointer(y) which is false
So to overcome this you need to use .Equals() which instead of reference compares the value and object type.
Console.WriteLine(y.Equals(x)); //compares "mehdi emrani" == "mehdi emrani" results true