A.s. Bhullar
A.s. Bhullar

Reputation: 2788

How can i differ two same objects in c#?

Pardon me,I am not very good in explaining questions. I can better explain my question through following example:

string first = "hello";
string second = "Bye";
first = second;

In the above example,consider the third line first=second .
Here i assigned object second to first. Because strings in c# are immutable i.e Every time you assign a new value to an existing string object, a new object is being created and old object is being released by the CLR.(I read this from here1). So simply it means the object first in first line is different from object first in third line.

So My question is how can i prove both are different?
i.e if it(string) is possible in C then i can print address of both objects before and after the third statement to prove it.
Is there any method to access there addresses or other alternatives are there?

Upvotes: 1

Views: 183

Answers (6)

Vilx-
Vilx-

Reputation: 107052

You've misunderstood what you've read. Yes, strings are immutable. That means you cannot change an existing string. This won't work:

string x = "Hello";
x[3] = 'q';

When you're concatenating strings, you get a new one:

string a = "a";
string b = "b";
string c = a+b; // You get a new string and a and b are unchanged.

Even when you're self-concatenating, you get a new string:

string a = "a";
a += "b"; // The same as a = a + "b" and yields a new string.

But assigning to a variable (or passing to a function, or returning from a function, etc) does NOT create a new string.

Strings are "reference types". That means that this variable:

string a = "Hello";

Is just a reference to the string. Doing this:

string b = a;

Just assigns the reference to the variable. It does not alter the string.

Or, to put it in C terms: Reference variables are pointers to objects. Consider:

string a = "Hello"; // a now points to the string object
string b = a; // b now points to the same object.

What the immutability means is that you cannot change the memory that the pointer points to (the string object itself). But the pointer variable is as changeable as ever. You can assign a different address to it.

To return to your original example:

string first = "hello"; // Allocates memory for "hello" and points first to it.
string second = "Bye";  // Allocates memory for "Bye" and points second to it.
first = second;         // Assigns the address of second to first.

In the end, both first and second point to the same address, which is the address of the string Bye. The memory of the string hello is now unreferenced (there are no pointers to it, it's unreachable). The garbage collector will reclaim it sometime later.

Added: Yet another analogy with C. String variables .NET are somewhat like this:

const char* str;

It's a pointer to a constant. You can change the pointer, but you cannot change the stuff that it points to.

Added 2: You should read up on Value Types vs Reference Types in .NET. In a nutshell, value types are all struct types, and reference types are all class types. Value types get copied on assignment (or when passed/returned from a function); reference types are pointers.

Note that there is one unintuitive piece here. The class object, which is the base class of ALL types, is a reference type. Yet Value Types inherit from it, and you can assign a Value Type to a variable of type object. If you do it, this will cause something called boxing and it involves making a copy of the value, so it's a bit of an expensive operation.

Upvotes: 1

Gene
Gene

Reputation: 4242

If you'd like to see the physical location in memory, you can use the following (unsafe) code.

private static void Main(string[] args)
{
  unsafe
  {
    string first = "hello";

    fixed (char* p = first)
    {
      Console.WriteLine("Address of first: {0}", ((int)p).ToString());
    }

    string second = "Bye";

    fixed (char* p = second)
    {
      Console.WriteLine("Address of second: {0}", ((int)p).ToString());
    }

    first = second;

    fixed (char* p = first)
    {
      Console.WriteLine("Address of first: {0}", ((int)p).ToString());
    }
  }
}

Sample output on my machine:

Address of first: 41793976 
Address of second: 41794056
Address of first: 41794056

You'll notice, that .NET caches the string instances which is perfectly valid because they are immutable. To demonstrate this behavior, you can change second to hello and all memory addresses will be the same. That's why you shouldn't rely on native memory stuff and just use the managed ways to work with objects.

See also:

The common language runtime conserves string storage by maintaining a table, called the intern pool, that contains a single reference to each unique literal string declared or created programmatically in your program. Consequently, an instance of a literal string with a particular value only exists once in the system.

Source: String.Intern (MSDN)

Upvotes: 5

Vikash Singh
Vikash Singh

Reputation: 814

for this you should get memory address of first first variable before assigning second to it and again check the memory address after assigning.

for getting the address of string follow this link

may this help you

Upvotes: 1

Baldrick
Baldrick

Reputation: 11860

If you have to compare the underlying memory addreses, the following unsafe code might help you (untested):

string first = "hello";


GCHandle handle = GCHandle.Alloc(first, GCHandleType.Pinned);
IntPtr address = handle.AddrOfPinnedObject();


string second = "Bye";
first = second;


GCHandle handle = GCHandle.Alloc(first, GCHandleType.Pinned);
IntPtr address2 = handle.AddrOfPinnedObject();

if (address != address2)
{
    // memory addresses are different afterwards
}

Upvotes: 1

fredrik
fredrik

Reputation: 6638

I believe that you want the ReferenceEquals method. It can be used to check if two instances of the object are exactly the same - i.e. references the same object.

Upvotes: 3

Mahmoud Hashim
Mahmoud Hashim

Reputation: 550

*you can use the .Equals() method or HashCode() method to compare *

Upvotes: 1

Related Questions