Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Class Objects and Equals Operator

Class Objects and Equals Operator

Scheduled Pinned Locked Moved C#
question
16 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B budidharma

    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#?

    F Offline
    F Offline
    Febret
    wrote on last edited by
    #7

    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

    1 Reply Last reply
    0
    • M Marc 0

      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

      B Offline
      B Offline
      budidharma
      wrote on last edited by
      #8

      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.

      M 1 Reply Last reply
      0
      • B budidharma

        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.

        M Offline
        M Offline
        Marc 0
        wrote on last edited by
        #9

        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 the Copy 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

        B 2 Replies Last reply
        0
        • M Marc 0

          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 the Copy 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

          B Offline
          B Offline
          budidharma
          wrote on last edited by
          #10

          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?

          M 1 Reply Last reply
          0
          • B budidharma

            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?

            M Offline
            M Offline
            Marc 0
            wrote on last edited by
            #11

            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

            1 Reply Last reply
            0
            • B budidharma

              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?

              S Offline
              S Offline
              S Senthil Kumar
              wrote on last edited by
              #12

              Or you can use a nifty little serialization[^] to do the copying for you. Regards Senthil _____________________________ My Blog | My Articles | WinMacro

              M 1 Reply Last reply
              0
              • M Marc 0

                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 the Copy 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

                B Offline
                B Offline
                budidharma
                wrote on last edited by
                #13

                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.

                B 1 Reply Last reply
                0
                • B budidharma

                  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.

                  B Offline
                  B Offline
                  budidharma
                  wrote on last edited by
                  #14

                  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.

                  M 1 Reply Last reply
                  0
                  • B budidharma

                    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.

                    M Offline
                    M Offline
                    Marc 0
                    wrote on last edited by
                    #15

                    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

                    1 Reply Last reply
                    0
                    • S S Senthil Kumar

                      Or you can use a nifty little serialization[^] to do the copying for you. Regards Senthil _____________________________ My Blog | My Articles | WinMacro

                      M Offline
                      M Offline
                      Marc 0
                      wrote on last edited by
                      #16

                      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

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups