Advertisement

Another C# question..

Started by December 18, 2002 05:02 AM
17 comments, last by NotAnAnonymousPoster 21 years, 11 months ago
I''m not trying to do anything useful. I just wanted to write a little test program. After I read each chapter in Programming C# I will try and implement an example of what I learned and that usually involves writing the most trivial and pointless classes imaginable. In this little program I was just seeing if I can get my own hash code function to work. But thanks for the info, if I ever need a point struct I know there''s one already made.
"C combines all the power of assembly language with all the ease of use of assembly language"
Mutable - an object whose state can be changed. Immutable objects cannot be changed after creation - they effectively have value semantics, even while heap allocated.

The reason mutable objects suck as hash keys is that if you change their internal state, their hashcode will change and the hashtable won''t be able to find it.


For those who believe in God, most of the big questions are answered. But for those of us who can''t readily accept the God formula, the big answers don''t remain stone- written. We adjust to new conditions and discoveries. We are pliable. Love need not be a command or faith a dictum. I am my own God. We are here to unlearn the teachings of the church, state, and our educational system. We are here to drink beer. We are here to kill war. We are here to laugh at the odds and live our lives so well that Death will tremble to take us -- Charles Bukowski
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Advertisement
So to make the object immutable I could just define the constructors but make all the properties read only?

In the case of a point class, wouldn''t I want to be able to still allow the x,y properties to be altered. That way if I changed a point from (0,0) to (3,5) it would change from "a corner shop" to "a house" when I looked it up in the hash table.

In what way does an immutable object have value semantics? i.e: What *are* value semantics? I know that value types exist on the stack and get passed by value but that''s about it.

One other thing about value types. It says in my book that if a struct inherits an interface and its methods are accessed through an interface reference, it is the boxed type that gets altered and not the original struct. It says as a design guideline that you shouldn''t access structs from an interface reference, but wouldn''t it be a better design guideline to never inherit an interface in a struct in the first place?
"C combines all the power of assembly language with all the ease of use of assembly language"
quote: Original post by NotAnAnonymousPoster
So to make the object immutable I could just define the constructors but make all the properties read only?

Yes.
quote:
In the case of a point class, wouldn''t I want to be able to still allow the x,y properties to be altered. That way if I changed a point from (0,0) to (3,5) it would change from "a corner shop" to "a house" when I looked it up in the hash table.

If you change an object you have used as a hashtable key, that won''t change it''s location internally in the hashtable. Basically, you won''t be able to find the object ever again since the hashcode will now be different.
quote:
In what way does an immutable object have value semantics? i.e: What *are* value semantics? I know that value types exist on the stack and get passed by value but that''s about it.

I was referring mainly to the fact that you can pass a reference to an immutable object to another method without worrying that the method might change the state of the object. This works the same as if you had passed a primitive to the method.
Immutable objects also behave somewhat like value types when it comes to aliasing - you can have multiple references to the same object without worrying that it might be modified through one of the references.
quote:
One other thing about value types. It says in my book that if a struct inherits an interface and its methods are accessed through an interface reference, it is the boxed type that gets altered and not the original struct. It says as a design guideline that you shouldn''t access structs from an interface reference, but wouldn''t it be a better design guideline to never inherit an interface in a struct in the first place?

Hard to avoid - think of things like IComparable, IConvertible etc... But most of the interfaces implemented by value types in the BCL don''t have methods that expect to modify the object.


For those who believe in God, most of the big questions are answered. But for those of us who can''t readily accept the God formula, the big answers don''t remain stone- written. We adjust to new conditions and discoveries. We are pliable. Love need not be a command or faith a dictum. I am my own God. We are here to unlearn the teachings of the church, state, and our educational system. We are here to drink beer. We are here to kill war. We are here to laugh at the odds and live our lives so well that Death will tremble to take us -- Charles Bukowski
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
quote: Original post by Arild Fines
If you change an object you have used as a hashtable key, that won''t change it''s location internally in the hashtable. Basically, you won''t be able to find the object ever again since the hashcode will now be different.

I don''t get it.

  class Point{	public Point(int x, int y)	{		this.x = x;		this.y = y;	}	public int X { get {return x;} set {x = value;} }	public int Y { get {return y;} set {y = value;} }		public override string ToString()	{		return "(" + x + "," + y + ")";	}	public override bool Equals(object rhs)	{		Point p = rhs as Point;		if (p != null)		{			return (p.x == x && p.y == y);		}		return false;	}	public override int GetHashCode()	{		return x^y;	}		private int x,y;}namespace Hashtables{	using System;	using System.Collections;	/// <summary>	/// Summary description for Class1.	/// </summary>	class Hashtables	{		/// <summary>		/// The main entry point for the application.		/// </summary>		[STAThread]		static void Main(string[] args)		{			Hashtable myHT = new Hashtable();			myHT.Add(new Point(3,5), "a house");			myHT.Add(new Point(1,2), "a church");			myHT.Add(new Point(0,0), "a corner shop");			Point point = new Point(0,0);			Console.WriteLine(point + "=" + myHT[point]);			point.X = 3;			point.Y = 5;			Console.WriteLine(point + "=" + myHT[point]);			point.X = 1;			point.Y = 2;						Console.WriteLine(point + "=" + myHT[point]);		}	}}  

That works fine. Are you talking about something different?

quote:
I was referring mainly to the fact that you can pass a reference to an immutable object to another method without worrying that the method might change the state of the object. This works the same as if you had passed a primitive to the method.

Thought that might be what you meant. But you can pass primitives with the ref or out keywords.

quote:
Hard to avoid - think of things like IComparable, IConvertible etc... But most of the interfaces implemented by value types in the BCL don''t have methods that expect to modify the object.

Guess you have to be careful about how you write interfaces and use structs then. Scott Meyer''s needs to write Effective C#. There is a website where someone has tried to make their own version but I don''t know how good it is.
"C combines all the power of assembly language with all the ease of use of assembly language"
quote: Original post by NotAnAnonymousPoster
That works fine. Are you talking about something different?

You're not modifying the key itself. Imagine if you were doing something like this:

      Point key = new Point( 4, 2);hashTable[ key ] = "forty two";key.x = 6;key.y = 9;object obj = hashTable[ new Point( 4,2 ) ]; //will return null since key no longer is at (4,2)object obj2 = hashTable[ new Point( 6,9) ]; //will _probably_ return null                                             //since key will be in wrong bucket  

quote:
Guess you have to be careful about how you write interfaces and use structs then.

Indeed.
quote:
Scott Meyer's needs to write Effective C#.

He has actually appeared briefly on the C# ng a while ago(might have been a fake, but he seemed genuine) and someone asked him that exact question. See these: http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=MPG.16fb3c932d7ac291989691%40msnews.microsoft.com&rnum=5&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3Dscott%2Bmeyers%26btnG%3DGoogle%2BSearch%26meta%3Dgroup%253Dmicrosoft.public.dotnet.languages.csharp and http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=MPG.1712ed09b743ee4f9896ca%40news.hevanet.com&rnum=2&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3Dscott%2Bmeyers%26btnG%3DGoogle%2BSearch%26meta%3Dgroup%253Dmicrosoft.public.dotnet.languages.csharp

While we are waiting, might I suggest checking out Jeffrey Bloch's Effective Java? It is written in the same style as the Meyers' books, and most of the Java stuff applies to C# in some degree. [/source]


For those who believe in God, most of the big questions are answered. But for those of us who can't readily accept the God formula, the big answers don't remain stone- written. We adjust to new conditions and discoveries. We are pliable. Love need not be a command or faith a dictum. I am my own God. We are here to unlearn the teachings of the church, state, and our educational system. We are here to drink beer. We are here to kill war. We are here to laugh at the odds and live our lives so well that Death will tremble to take us -- Charles Bukowski

[edited by - Arild Fines on December 19, 2002 2:05:00 PM]
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]
Advertisement
Arild: http://www.makeashorterlink.com/
Again...bugger. I''ve just thought it all through and I think I''ve got it. I didn''t think through how hash tables would be implemented. If I had I probably would have realised that Equals() would be a necessity. The object which you provide as the key must be compared with the object it finds in the bucket, which is the object you originally used to create the entry in the hashtable. So any change to the original object is going to cock things up. And in my example I created the original key with new so the only reference to it would exist in the hashtable itself. Is that right?
"C combines all the power of assembly language with all the ease of use of assembly language"
Yes.

Alimonster: Point taken
--AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [IRC channel] [Blog]

This topic is closed to new replies.

Advertisement