How can i differ two same objects in c#? - 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?

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)

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.

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

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
}

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

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.

Related

Returning array from methods C#

I have been wondering, why isn't my method, modifying the array, when I used it as a parameter and made it equal to another array with different values, inside the method?
Am I just changing the reference address?
static void Main()
{
string[] array = { "yes", "no", "maybe" };
TestO(array); // Still "yes", "no", "maybe"
}
static void TestO(string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
My guess: I did not modify the array inside the Main(), because when doing array = secondArray; in the Test0() method,
I just changed the reference address of array to secondArray.
If my guess is not right, my question is, why exactly is it not getting modified?
(I know that I can just modify Test0() to a string[] return method and return the modified secondArray and pass it on to the array in Main())
Another questions is:
If I use the string[] return method, and declare the following:
static void Main()
{
string[] array = { "yes", "no", "maybe" };
array = TestO(array);
}
static string[] TestO(string[] methodArray)
{
string[] secondArray = new string[methodArray.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
return secondArray;
}
array = TestO(array); am I just passing the reference address of the secondArray[] to array[] or am I passing only the values of it? (Most probably it will be the reference address, but I wanted to be sure if mistaken)
I just changed the reference address of array to secondArray. If my guess is not right, my question is, why exactly is it not getting modified?
I think you're leaning towards appreciating that there are two references to one data in memory (there are not two data); you have a variable array that points to data. You call a method and another, copy reference is established to the same data. You made a new object, then you pointed the copied reference at the new object, leaving the original reference pointing to the original data, then you threw the copy reference and the new data away.. You're back to the exact same situation you started with.
Pictorially, line by line, it might look like (I renamed your method argument to arrayX so the difference is obvious):
If you decorate the argument with ref and call it with ref there is no copy, so the called method can modify the original reference and point it somewhere else:
Note that in either of these cases it's perfectly possible to modify the contents of the array. Doing:
arrayX[0] = "New data";
..would take effect in either case and printing array[0] would show "New data". When modifying the data at the end of the arrow it matters not whether the starting point is an original reference or a copy. This is purely about whether the method has the power to point the original reference passed to it, to a different object or not
Generally we don't do it. We adopt the style of your second code block - to return the data. It may help to see it as rude - imagine your friend says he'll look after your plant while you're on holiday; you give your keys to your friend. He swaps your plant for a different one that he likes better; you're upset because you had that plant for ten years..
There are very few reasons to use ref, or the related "power to overwite your reference" - out. Don't use it for "I wanted to return multiple things from my method" - in an OO world we can always return one thing that represents two items of data. We don't need to "return two things"; we can return one thing with two things inside it...
//don't:
void GetPerson(ref string name, ref int age)
//consider a class:
Person GetPerson()
return new Person(){ Name = ..., Age = ...}
//or a Tuple
(string Name, int Age) GetPerson
Let the calling method choose whether its own variable should be overwritten, rather than having some "third party" pull that rug from under its feet
you don't need to return anything , just use a ref
static void Test( ref string[] array)
{
string[] secondArray = new string[array.Length];
secondArray[0] = "1";
secondArray[1] = "2";
secondArray[2] = "3";
array = secondArray;
}
When you pass an array to a method
static void Test0(string[] array)
{
You are passing a reference to that array. That reference is effectively immutable (you're getting a copy of the reference, not the original one), so you can't change the parameter reference and expect it to affect the code outside of the Test method.
While you can do this to get the behavior you want:
static void Test0(ref string[] array)
{
it's not considered good C# style. Strings are themselves immutable; the "correct" style is to return them from the method. This is also true of string arrays.
The only thing you would be saving by using this technique is an extra reference and a return statement, since you're still creating new strings and a new array anyway.

Difference between Reference Type and Value type in case of string in c#

Ok, So I am a beginner in C# and I learned the concept of Reference Type and Value Type. Also I understood that Value type is on Stack where as Reference types are stored in Heap. And then we need to to manually allocate memory to Reference type and all of that. But I am not able to understand below Behaviour. Please guide me.
Example 1:
var arr1 = new int[3] { 1, 2, 3 }; // memory allocated
var arr2 = arr1; // another variable created but pointing to same memory in Heap
arr2[0] = 2; // value in array 2 changed
System.Console.WriteLine("");
foreach (var item in arr1)
{
System.Console.WriteLine(item);
}
System.Console.WriteLine("------------");
foreach (var item in arr2)
{
System.Console.WriteLine(item);
}
Output as :
arr1: 2,2,3
arr2: 2,2,3
Conclusion: Since both were pointing to same memory location. So, when value in Array 2 is changed the value in Array1 also got affected. So far so good.
Now there is one more reference type which is string.
Consider below Example 2:
var Name = "Mosh";
var FName = Name;
FName = "Hello";
System.Console.WriteLine(Name);
System.Console.WriteLine(FName);
Output as:
Mosh
Hello
Expected Output:
Hello
Hello
Since I changed the value for FName I was expecting the Name value also to be changed as both must be pointing to same memory location. It's one of the simplest question on SO, I am a beginner so bear with me.
In the .Net Framework a String is an immutable reference type.
Since a String does not have a pre-defined memory size (as the value types that can be stored in the Stack), it can grow large (approx. 2 billion Unicode characters), and requires dynamic memory allocation. When a String object is created, the actual value is stored within dynamic memory, the Heap.
Immutable means, it cannot be changed after it has been created. Every change to a string will create a new string. This is why all of the String manipulation methods return a string.
Reference types have some overhead on construction and destruction and
garbage collection, because they are created on the heap. Value types
on the other hand have overhead on method calls (if the data size is
larger than a pointer), because the whole object is copied rather than
just a pointer. Because strings can be much larger than the size of a
pointer, they are designed as reference types. Ref.
In your case: When you assign Name to FName: FName = Name both Strings reference the same Object (as shown in the code sample) that contains the string "Mosh" in the Heap. After FName has ben set to another string value it references a different memory location that stores the new string "Hello". Name keeps pointing to original memory location that stores "Mosh" and remains unchanged.
This behavior of String as value type is less obvious when it is used as a parameter that updates the value in the function. As long as the String parameter is not provided by reference it's original value will not be changed (see sample).
using System;
public class Program
{
public static void Main()
{
var Name = "Mosh";
var FName = Name;
Console.WriteLine(Object.ReferenceEquals(Name,FName));
FName = "Hello";
System.Console.WriteLine(Name);
System.Console.WriteLine(FName);
Console.WriteLine(Object.ReferenceEquals(Name,FName));
TestFunc(Name);
System.Console.WriteLine(Name);
RefFunc(ref FName);
System.Console.WriteLine(FName);
}
public static void TestFunc(string test)
{
test = "after passing";
}
public static void RefFunc(ref string test)
{
test = "after passing";
}
}
Your confusion comes in part because you see both these statements as somewhat equivalent in nature. They are not!
arr2[0] = 2;
FName = "Hello";
In the first case, the array that arr2 is pointing to is modified. But, arr2's reference to that array is unchanged. So both arr1 and arr2 keep pointing to the same array and both see the changes to the array.
In the second case however, it is not the object that FName points to that is being changed. That is to say, we are not modifying the "Mosh" string in any way. Rather, we are changing FName's reference to point a different memory location where the immutable string "Hello" resides in the heap. After this point, FName no longer points to the same memory location as Name. Name keeps pointing to the "Mosh"'s memory location, which remains unchanged.
A string in a reference type yes, but by C#'s design it will more or less behave like other primitives / value types.
To get the effect you're mentioned you would have to specify that a value is a pointer, something similar to: string* PName = Name;
Your question, "Is it safe to say they are pointing at the same location in memory?" I'm not actually sure, though I know that strings do not have a fixed address in memory, so you cannot use "&" or "GetHashCode" like you can to test this on integers or other types.
Edit 1:
Well I'll be a monkey's uncle, you're right. Try this:
Console.WriteLine(Object.ReferenceEquals(Name,FName)

Assigning a string-literal to a string in C#

Do string-literals have a particular type in C# (like const char* in c++) or does C# just create a new string object for each string-literal that appears in a program ?
I am curious to understand what happens behind the scene when the following statement is executed:
string s1 = "OldValue";
does this call a particular method in the string class (a constructor, or an impicit conversion operator, ...) or does C# create a new string object that contains "OldValue" ( then just assign its reference to s1, just like it would for any reference type ) ?
i am trying to understand what it is in the design of the string class that garantees the value of s1 remains "OldValue":
string s2 = s1;
s2 = "NewValue";
To you last question, why values were preserved - it is not in the String class. It is in the way that object references work.
The String class is not a value type, it is a reference type. It is a full-featured object that is not copied-around when "passed intto/from variables".
When you write:
string s1 = "mom";
string s2 = s1;
string s3 = s1;
s3 = "dad";
there is only one instance of "mom", that is first created somewhere in the heap, then a reference to it is assigned to s1. Then another reference is created and assigned to s2. Then another reference is created and assigned to s3. No copies. References. Like for any real, normal CLR object.
Finally, in the last line, another string is created on the heap and then a reference to it is assigned to the s3 variable. Note that this sentence says absoltely nothing about the "mom" or s1/s2 variables. They didn't note a thing.
Remember that String is not a value-type. It is just an normal immutable object that has some handy Equals and GetHashCode overrides. String class has some little magic inside, but it is not relevant here.
Good question.
Actually in c# strings are stored in the format of buffer array where in every string declaration required 20bytes to store data and post that 2 bytes for each character.
so whenever you declare any string for e.g. string s1 = 'Bhushan';
then on string buffer will be created and will have memory requirements as follows,
Bytes required for Data (Overhead) : 20 Bytes
2 bytes per character so (2 * 7) : 14 Bytes
Overall it will required 20 + 14 = 34 Bytes.
string is an immutable class, that means every time we change the value, it will create new instance.
string s2 = s1;
s2 = "NewValue";
it can be explain like this.
string s2 = s1;
s2 = new string("NewValue"); // It doesn't compile, just an example.
And for string modification, it can be explained like this.
string s = "blah";
s.Insert(0, "blah"); // s is a new instance
The same like:
string s = "blah";
s = new string("blah") + new string("blah"); // Doesn't compile, just an explanation

String - Difference between Clone, Copy, and Standard Affectation

I've just come across a block like this while browsing through legacy code :
object exeName = _connectionSettings.ApplicationName.Clone();
RandomFunction(exeName);
It seemed useless to me at first, but it made me wonder. Is there a fundamental difference between:
var copiedString = initialString;
var copiedString = initialString.Clone();
var copiedString = string.Copy(initialString);
I've created a basic unit test that seems to show there is none since it behaves the same way regardless of the method used (initial affectation of copiedString, change of the initialString, assertion of copiedString value) . Am I missing something?
Using Reflector to look at the implementation of String.Clone() reveals this:
public object Clone()
{
return this;
}
So the answer is "No, there is no difference between assigning and cloning for a string".
However, Copy() is somewhat different:
public static unsafe string Copy(string str)
{
if (str == null)
{
throw new ArgumentNullException("str");
}
int length = str.Length;
string str2 = FastAllocateString(length);
fixed (char* chRef = &str2.m_firstChar)
{
fixed (char* chRef2 = &str.m_firstChar)
{
wstrcpy(chRef, chRef2, length);
}
}
return str2;
}
This is actually making a copy - but since strings are immutable, it's not very useful anyway.
But - and this is important - Copy() will return a DIFFERENT REFERENCE from the original string, and Clone() will return the SAME REFERENCE as the original string.
Another thing to be aware of is string interning which causes strings with identical values to share the data (and therefore have the same string reference).
For example, the following code will print "Same!":
string s1 = "Hello";
string s2 = "Hello";
if (ReferenceEquals(s1, s2))
Console.WriteLine("Same!");
But the following code will print "Not same!", even though the string values are the same:
string s1 = "Hello";
string s2 = "He";
string s3 = "llo";
string s4 = s2 + s3;
if (!ReferenceEquals(s1, s4))
Console.WriteLine("Not Same!");
We can explicitly intern s4, so that the following prints "Same!":
string s1 = "Hello";
string s2 = "He";
string s3 = "llo";
string s4 = s2 + s3;
s4 = string.Intern(s4);
if (ReferenceEquals(s1, s4))
Console.WriteLine("Same!");
String.Clone() does nothing but return the reference to the same string (see here)
But since strings in C# are immutable anyway, there's no difference between all three methods you've specified.
Since the CLR implements immutable strings, and treats strings like values, semantically, the only time it would ever be an issue in correct code is outside of the managed code sandbox.
In context of managed code, strings should be simply assigned, just like int and byte and float.
Since the CLR implements immutable strings, and treats strings like values, semantically, the only time it would ever be an issue in correct code is outside of the managed code sandbox, and even so, correct code would properly consider all aspects of CLR strings (as in 2 strings may refer to the same "value").
In context of managed code, strings should be simply assigned, just like int and byte and float.

How to get a list of mutable strings?

I have the following piece of code
List<String> l = new List<String>();
String s = "hello";
l.Add(s);
s = "world";
When I set up some breakpoints and go through the program, after executing the last line, the value in the list is still hello instead of world.
Shouldn't it equal world ? Isn't a string an object, and am I not just inserting a pointer into the list? Later on if I change the string to point to a different value ("world"), why is my list still referencing the old value?
How can I get my desired effect ?
Thanks a lot!
Strings are immutable so that won't work. When you attempt to set into it, you actually drop the pointer to the old string and create a new one under the hood.
To get the desired effect, create a class that wraps a string:
public class SortOfMutableString
{
public string Value {get;set;}
public SortOfMutableString(string s)
{
Value = s;
}
public static implicit operator string(SortOfMutableString s)
{
return s.Value;
}
public static implicit operator SortOfMutableString(string s)
{
return new SortOfMutableString(s);
}
}
And use this in your list. Then references will point to the class, but you can contain the string value inside. To make it even better, override implicit casting to and from string so you don't even need to see that you are talking to a SortOfMutableString.
Refer to Jon Skeet's answer for undoubtedly a very accurate explanation about string's in C#, I'm not even going to bother!
Alternative class names:
PseudoMutableString
ICantBelieveItsNotMutable
HappyAndReferenceableString
You're changing the s reference to refer to a different String instance.
Strings are immutable; it is impossible to change the existing instance that you added to the list.
Instead, you can create a mutable StringHolder class with a writable String property.
No, it shouldn't equal world. The value of the variable s is a reference. When you call l.Add(s), that reference is passed by value to the list. So the list now contains a reference to the string "hello".
You now change the value of s to a reference to the string "world". That doesn't change the list at all.
It's important to distinguish between three very different concepts:
A variable (which has a name and a value)
A reference (a value which allows you to navigate to an object, or null)
An object
So in particular, the list doesn't know anything about the variable s - it knows about the value which was passed into Add; that value happened to be the value of s at the time Add was called, that's all.
You may find these articles helpful:
Values and references
Parameter passing in C#
No, there are two different references involved. One called s and one that's at List[0]. When you say l.Add(s) you are setting the list reference to the same address as s, but then when you assign s to "world", then s will point to the new string, leaving List[0] pointing to the old string.
If you really want to do something like what you are asking, you'd need to wrap the string in another object that contains a string, so that s and List[0] both refer to that object, and then that object's reference to a string can change and both will see it.
public class StringWrapper
{
public string TheString { get; set; }
}
Then you can do:
var s = new StringWrapper { TheString = "Hello" };
var l = new List<StringWrapper>();
l.Add(s);
s.TheString = "World";
And now l[0].TheString will be world too. This works because in this case we are not changing the reference in List[0] or s, but they contents of the object referred to by s and List[0].
A variable is an object reference, not an object itself. s = "world" says "make s refer to the string "World") - it does not in any way affect the string "hello" that s was previously referring to. Furthermore, strings in C# are always immutable. You can, however, make the first list element (which currently refers to "hello") refer to a different string: l[0] = "world".
The other two answers here did a great job of saying why what you tried didnt' work, but you were looking for a solution for your desired effect. Wrap a string (property) inside of an object. Then you can change that string and it will be reflected in the collection.

Categories