Why ReferenceEquals and == operator behave different from Equals

前端 未结 3 1144
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-19 20:55

I have an Entity that doesn\'t override any of the equality members\\operators.
When comparing two proxies of them (I got them from the Nhibernate session)

相关标签:
3条回答
  • 2021-01-19 21:10

    If ReferenceEquals returns false, you are clearly comparing two different instances.

    Equals might still be true if it's overridden, but I don't think that's where the actual problem is.

    I'd like to know how you're mapping and getting those objects, because as the docs say, you can never get two different objects of the same type representing the same row in the same session.

    0 讨论(0)
  • 2021-01-19 21:21

    Edit

    You might be using a struct? See below


    I suppose reference types show the behaviour you expect:

    public class Program    {
        class X { int x,y; }    
        public static void Main(string[] args)
        {
            X a = new X();
            X b = new X();
            System.Console.WriteLine(a == b);
            System.Console.WriteLine(a.Equals(b));
            System.Console.WriteLine(Equals(a,b));
            System.Console.WriteLine(ReferenceEquals(a,b));
    } }
    

    Prints:

    False
    False
    False
    False
    

    For structs, things are different (commeting out the a==b test, which doesn't compile for structs:)

    public class Program {
        struct X { int x,y; }
        public static void Main(string[] args)
        {
            X a = new X();
            X b = new X();
            //System.Console.WriteLine(a == b);
            System.Console.WriteLine(a.Equals(b));
            System.Console.WriteLine(Equals(a,b));
            System.Console.WriteLine(ReferenceEquals(a,b));
    } }
    

    Output:

    True
    True
    False
    

    Rationale:

    The default implementation of Equals() comes from class ValueType, which is implicit base class of all value types. You may override this implementation by defining your own Equals() method in your struct. ValueType.Equals() always returns false when one compares objects of different (dynamic) types. If objects are of the same type, it compares them by calling Equals() for each field. If any of these returns false, the whole process is stopped, and final result is false. If all field-by-field comparisons return true, final result is true

    0 讨论(0)
  • 2021-01-19 21:21

    After I get childs from the session I Merge them with the session.

    var childs = session.Query<Child>();
    // Do some stuff
    foreach (var child in childs)
    {
        session.Merge(child);
    }
    
    var parents = childs.Select(x => x.ParentEntity).ToList(); 
    

    It appear that the merge detached the entity from the session and return a new Proxy attached to the session.

    It can be fixed with

    var newChild = (Child)session.Merge(child);
    // Or:
    session.Update(child); // (We have session.Clear() in our tests so I can't use this because it makes troubles when you update detached Entity
    
    0 讨论(0)
提交回复
热议问题