Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Compare a reference of class to "this" to see if it's literally the same and not just the same type

Discussion in 'Scripting' started by TheCelt, May 10, 2016.

  1. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    724
    Hello

    I have a basic list that stores references like this:

    Code (csharp):
    1.  
    2. public class Room {
    3.      Handler handler;
    4.  
    5.      public Room(Handler h){
    6.          handler = h;
    7.      }
    8. }
    9.  
    This is all setup fine, but i want to be able to check in my Handler class if it is the same script that my list has a reference to.


    So i have this handler component with this method:

    Code (CSharp):
    1. public Room room;
    2.  
    3. void SetRoomLink(){  
    4.         for(int i = 0; i < rooms.Count; i++){
    5.               if(ReferenceEquals(this,rooms[i].handler)){
    6.                  room = rooms[i];
    7.                  break;
    8.             }
    9.         }
    10. }
    That did not work, so then i tried this:

    Code (CSharp):
    1. public Room room;
    2.  
    3. void SetRoomLink(){
    4.         for(int i = 0; i < rooms.Count; i++){
    5.               if(rooms[i].handler == this)){
    6.                  room = rooms[i];
    7.                  break;
    8.             }
    9.         }
    10. }
    This also didn't work, the comparison is never true. So it seems i can't compare a reference to a precise script to see if it is the same reference instance. (Not sure if i am using the right terminology?)

    Is there a way to do what I am trying to do here? Each game object component would have a copy of the room it is referred to as from the rooms list.
     
  2. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,663
    Perhaps keep an ID variable you set in the constructor, then just compare that later...

    Code (CSharp):
    1. public class Room {
    2.      Handler handler;
    3.      public int ID;
    4.      public Room(Handler h,  int _ID){
    5.          handler = h;
    6.          ID = _ID;
    7.      }
    8. }
    9.  
    10.  
    11. // elsewhere...
    12. if (someRoom.ID == rooms [i].ID)
    13. {
    14. // same room
    15. }
     
  3. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    724
    Can i not compare via memory pointer or something?
     
  4. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,663
    Not something that I could tell you how to do. Perhaps others can suggest alternatives.
     
  5. Manny Calavera

    Manny Calavera

    Joined:
    Oct 19, 2011
    Posts:
    205
    Yes, you can compare by reference. Using ==, this or even ReferenceEquals(). But without looking at the whole code it's hard to tell what's going on.

    However... That's usually not the way to go with managed code. Sure, in C++ there is pointer arithmetic and that makes sense in that context. But not in C#, specially if immutable types are involved.

    If you want to compare objects in C# you should consider implementing IEquatable<> in your Room class and use room1.Equals(room2).
     
  6. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    724

    I managed to get it working, but am curious why its not the way to go ? By storing a copy in the handler script, i won't have to iterate my list every time to find the relevant index of the list. Previously i was using LINQ but realized storing a copy of Room to the script meant i could just access that public value.
     
  7. Manny Calavera

    Manny Calavera

    Joined:
    Oct 19, 2011
    Posts:
    205
    Yes, you can store a reference to another object, no problem at all. But when comparing an object to another you should prefer an Equals() comparison rather than a reference comparison. Implement IEquatable if necessary.
     
  8. TheCelt

    TheCelt

    Joined:
    Feb 27, 2013
    Posts:
    724
    So i should not use == ? Can you show the syntax for the more correct way to do it.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    == can be overloaded. So it will return true if the instances are functionally equal. It's generally the best practice.

    ReferenceEquals will return true only if the instances point to the same memory location. Most of the time you don't need it.

    Example
    Code (CSharp):
    1. // Returns false
    2. ReferenceEquals("Dog","Dog");
    3.  
    4. // Returns true
    5. "Dog" == "Dog";