Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How a variable can have two values at the same time?

I guess with what I'm going to write I should first clarify, it's not something I would like to achieve. It is something that happened to me and I am trying understand how it is possible, so I can fix it. So here we go...

I'm using C#, .Net 4.0. The code is biggish, too big to past it all here but I try to explain what happens in hope that there is somebody knowledgeable who will have some thoughts.

In my call stack I have a series of generic methods and I have noticed that although the value should be just passed from one to the other it is changing. Ok, that was my first impression. Later I managed to isolate one problematic method in which when I stop I can see two different values for the same property of an object.

public class Sample : BaseClass, ISomeInterface
{
    [XmlIgnore]
    public new Guid Id { get; set; }
} 

What may be significant that both BaseClass and ISomeINterface define

public Guid Id

so now, when I stop in that generic method and watch variable data of Sample type i can expand its properties and see the first value of Id. But when I watch data.Id it shows different value. Have a look for yourself.

(Here was a picture which I cannot post due to a negligible reputation. Sorry)

Edit: I pushed it there http://picturepush.com/public/7307446

Would any body out there know what is the difference in how those values in the Watch window are obtained? What is the difference? I tried many different approaches, casting, using reflection but always I get the value the same as when you watch data.Id and ironically, the correct value, the one I expect is the other, elusive one.

Oh, and no, it is not a homework ;)

like image 728
michal Avatar asked Mar 20 '26 03:03

michal


2 Answers

The new keyword is hiding the base class member.

Set the Id property in BaseClass to virtual:

public class BaseClass : ISomeInterface
{
    public virtual Guid Id { get; set; }
}

And override it in Sample:

public class Sample : BaseClass, ISomeInterface
{
    public override Guid Id { get; set; }
}
like image 165
lukiffer Avatar answered Mar 21 '26 18:03

lukiffer


When you're defining Id in both the base class and actual class, the second definition isn't overriding the first but hiding it. This means that the Sample class actually contains both definitions and it depends on the static type of the variable which you access.

Hence:

Sample s = new Sample();
BaseClass b = (BaseClass)s;
s.Id != b.Id;

This is generally not what you want and can lead to quite strange behavior, as you've already found out :)

Simple compileable example that demonstrates this:

class A {
    public int val = 5;

    public static void Main(string[] args) {
        B b = new B();
        A a = (A)b;
        Console.WriteLine(a.val); // 5
        Console.WriteLine(b.val); // 10
    }
}

class B : A {
    public int val = 10;
}

If you already have this mess and can't fix it correctly, you can cast the static type to whatever version you want to access.

like image 24
Voo Avatar answered Mar 21 '26 18:03

Voo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!