Class Objects and Equals Operator
-
That's what I was afraid of. I don't want to set myobj2 to the location in memory of myobj. I want to copy all the data from myobj into myobj2. I don't want this to be written as structs. I know I could simply write a copy function: public static void Copy(mydef myobj, mydef myobj2) { myobj2.Set(myobj.Get()) } But that's a very long winded and very ... not elegant. What's the better method of doing this in C#?
As Marc said, you should implement the ICloneable interface. Notice that if you have to do a simple shallow copy as in the case you exposed, you don't have to write your own copy code, but you can use the Object.MemberwiseClone method instead. (You'll have to implement ICloneable anyway though, because MemberwiseClone is protected) Cheers
-
The usual/recommended way is to implement
IClonable.Clone
. What i usually do is something like this:// Not-tested code!
public class MyDef : IClonable {
...
// I always have a constructor like this:
protected MyDef(MyDef original){
// Copy all private fields from original
}
// Usually i implement IClonable:
public object Clone {
return new MyDef(this)
}
// You can also use your Copy approach
public static MyDef Copy(MyDef original){
return new MyDef(original)
}
...
}Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
-- modified at 12:28 Tuesday 1st November, 2005
Thank you. Above what you wrote is how I was thinking about doing it. But now that you've mentioned the ICloneable interface, I'd like to learn that method as well. I've been searching for a tutorial on this for over an hour, and have not found one. I'm not exactly how to use it. Can you explain a little bit about this? Thanks.
-
Thank you. Above what you wrote is how I was thinking about doing it. But now that you've mentioned the ICloneable interface, I'd like to learn that method as well. I've been searching for a tutorial on this for over an hour, and have not found one. I'm not exactly how to use it. Can you explain a little bit about this? Thanks.
I couldn't find a tutorial either, it's a shame ;P Anyway, here's round about i would do it. Of course, you can do it some other way if you want.
// Make class implement IClonable
public class MyDef : ICloneable
{
private int someInt;
private string someString;// Default constructor
public MyDef()
{
}// Protected constructor, for cloning/copying
protected MyDef(MyDef original)
{
// Copy all the fields from original
this.someInt = original.someInt;
this.someString = original.someString;
}// IClonable implementation
// Advantage: you've implemented IClonable, thats ususally a good thing if you want your class to be copyable
// Disadvantage: You have to manually cast the returned object to a MyDef
public object Clone()
{
return new MyDef(this);
}// If you want, you can do this (like your copy(obj1, obj2) idea)
// Advantage: -It's static, so you can just do MyDef.Copy(...)
// -The returned value is already of type MyDef, no need to typecast
// Disadvantage: It's not the way it's 'supposed' to go
public static MyDef Copy(MyDef original)
{
return new MyDef(original);
}
}If you want, you can use both the
Clone
and theCopy
way, it's just a matter of taste :). Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
-
I couldn't find a tutorial either, it's a shame ;P Anyway, here's round about i would do it. Of course, you can do it some other way if you want.
// Make class implement IClonable
public class MyDef : ICloneable
{
private int someInt;
private string someString;// Default constructor
public MyDef()
{
}// Protected constructor, for cloning/copying
protected MyDef(MyDef original)
{
// Copy all the fields from original
this.someInt = original.someInt;
this.someString = original.someString;
}// IClonable implementation
// Advantage: you've implemented IClonable, thats ususally a good thing if you want your class to be copyable
// Disadvantage: You have to manually cast the returned object to a MyDef
public object Clone()
{
return new MyDef(this);
}// If you want, you can do this (like your copy(obj1, obj2) idea)
// Advantage: -It's static, so you can just do MyDef.Copy(...)
// -The returned value is already of type MyDef, no need to typecast
// Disadvantage: It's not the way it's 'supposed' to go
public static MyDef Copy(MyDef original)
{
return new MyDef(original);
}
}If you want, you can use both the
Clone
and theCopy
way, it's just a matter of taste :). Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
Awesome, thank you very much. I also noticed that there is an IComparable interface. Am I correct in assuming that IComparable is implemented just like ICloneable, with the appropriote changes? And is it preferable to implement IComparable rather than overloading the == operator?
-
Awesome, thank you very much. I also noticed that there is an IComparable interface. Am I correct in assuming that IComparable is implemented just like ICloneable, with the appropriote changes? And is it preferable to implement IComparable rather than overloading the == operator?
You're welcome :-D You can also implement IComparable is you want, but that interface is normally used for sorting and stuff (according to MSDN[^], the Remarks section). To be honest, i never used IComparable, because i never sorted anything... :rolleyes: So if you don't want to sort, but just want to have a way of telling if the two instances are equal, I would override
Equals(obj)
. There's also a static overload of Equals, but you don't have to override that, because it just calls the Equals of the first object. And if you want, you can overload/overidde the == operator, and then just call Equals:public override bool Equals(object obj){
// Check if all fields are equal
// If so, return true, if not equal return false
}
// I never operator overloaded anything, so i hope this makes sense...
public operator ==(object obj){
return this.Equals(obj)
}For more info about Equals, IComparable and sucj, you can read this article: General Guidelines for C# Class Implementation[^] Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
-
I'm confused on the following: public class mydef { int int1; int int2; ... pubic void SetValues(int f, int s) {...} } mydef myobj; myobj.SetValues(1,2); mydef myobj2; myobj2 = myobj; // CAN I DO THIS? myobj.SetValues(3,4); ... What have I just done? Is it as straight forward as it seems? Did I simply set the values in myobj, create a new object and set it's values to those in myobj, and then modify the values in myobj without affecting myobj2? If not, how would I do this?
Or you can use a nifty little serialization[^] to do the copying for you. Regards Senthil _____________________________ My Blog | My Articles | WinMacro
-
I couldn't find a tutorial either, it's a shame ;P Anyway, here's round about i would do it. Of course, you can do it some other way if you want.
// Make class implement IClonable
public class MyDef : ICloneable
{
private int someInt;
private string someString;// Default constructor
public MyDef()
{
}// Protected constructor, for cloning/copying
protected MyDef(MyDef original)
{
// Copy all the fields from original
this.someInt = original.someInt;
this.someString = original.someString;
}// IClonable implementation
// Advantage: you've implemented IClonable, thats ususally a good thing if you want your class to be copyable
// Disadvantage: You have to manually cast the returned object to a MyDef
public object Clone()
{
return new MyDef(this);
}// If you want, you can do this (like your copy(obj1, obj2) idea)
// Advantage: -It's static, so you can just do MyDef.Copy(...)
// -The returned value is already of type MyDef, no need to typecast
// Disadvantage: It's not the way it's 'supposed' to go
public static MyDef Copy(MyDef original)
{
return new MyDef(original);
}
}If you want, you can use both the
Clone
and theCopy
way, it's just a matter of taste :). Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
God, I must be really annoying by now ... but I'm having some problem i can't seem to find. I'm sure I'm overlooking something stupid. ... relevant methods from the card class ...
public Card(Card c) { m_Rank = c.GetRank(); m_Suit = c.GetSuit(); } public object Clone() { return new Card(this); }
... relevant methods from the deck class ...public void Shuffle() { Random rand = new Random(); for (int i = 0; i < 52; i++) { int first = rand.Next(52); int second = rand.Next(52); // Copy data from random card 1 to tempcard // Copy data from random card 2 to card 1 // Copy data from tempcard to card 2 Card tempCard = m_Deck[first].Clone(); m_Deck[first] = m_Deck[second].Clone(); m_Deck[second] = tempCard.Clone(); } }
... Throws the error: Error 4 Cannot implicitly convert type 'object' to 'Poker.Card'. An explicit conversion exists (are you missing a cast?) C:\...\Cards.cs 246 33 Poker I tried to fix it myself, can't seem to figure out where the problem is. When I call clone, it creates a new object from this and returns it cast as a card. I thought I'd be able to simply set an object equal to that new object ... apparently not though. I also tried: Card c = new mycard.Clone(); ... that throws an error as well. Sorry for so many questions. Thank you for all the help. -
God, I must be really annoying by now ... but I'm having some problem i can't seem to find. I'm sure I'm overlooking something stupid. ... relevant methods from the card class ...
public Card(Card c) { m_Rank = c.GetRank(); m_Suit = c.GetSuit(); } public object Clone() { return new Card(this); }
... relevant methods from the deck class ...public void Shuffle() { Random rand = new Random(); for (int i = 0; i < 52; i++) { int first = rand.Next(52); int second = rand.Next(52); // Copy data from random card 1 to tempcard // Copy data from random card 2 to card 1 // Copy data from tempcard to card 2 Card tempCard = m_Deck[first].Clone(); m_Deck[first] = m_Deck[second].Clone(); m_Deck[second] = tempCard.Clone(); } }
... Throws the error: Error 4 Cannot implicitly convert type 'object' to 'Poker.Card'. An explicit conversion exists (are you missing a cast?) C:\...\Cards.cs 246 33 Poker I tried to fix it myself, can't seem to figure out where the problem is. When I call clone, it creates a new object from this and returns it cast as a card. I thought I'd be able to simply set an object equal to that new object ... apparently not though. I also tried: Card c = new mycard.Clone(); ... that throws an error as well. Sorry for so many questions. Thank you for all the help.God, I just figured out what you meant. You said with this method, I need to manually cast each return value, for example: Card tempCard = (Card)m_Deck[first].Clone(); Apparently it's because Clone returns an object. Screw that! I'm going to use the latter static method that returns a Card! Thanks again for all the help.
-
God, I just figured out what you meant. You said with this method, I need to manually cast each return value, for example: Card tempCard = (Card)m_Deck[first].Clone(); Apparently it's because Clone returns an object. Screw that! I'm going to use the latter static method that returns a Card! Thanks again for all the help.
You're not annoying at all, i'm happy to help! I'm glad you figured it out yourself. Of course, i can explain (almost) everything for you, but a real programmer can solve problems, i think. :cool: But that doesn't mean you should stop asking questions though! Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick
-
Or you can use a nifty little serialization[^] to do the copying for you. Regards Senthil _____________________________ My Blog | My Articles | WinMacro
That's true (and very cool :cool:), but: 1) The object you want to copy must be Serializable 2) I think (not tested) that it's slower than the usual way of Clone Pompiedompiedom... ;)
"..Commit yourself to quality from day one..it's better to do nothing at all than to do something badly.." -- Mark McCormick