Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this value in the struct not change at all?

Tags:

c#

interface

That's very simple question I believe. Could anybody explain why this code outputs 1000, not 1050

public class Program
    {
        public static void Main()
        {
            Bus b = new Bus(1000);
            ((Car)b).IncreaseVolume(50);
            Console.WriteLine(b.GetVolume());
        }
    }

    public interface Car
    {
        int GetVolume();
        void IncreaseVolume(int amount);
    }

    public struct Bus : Car
    {
        private int volume;

        public Bus(int volume)
        {
            this.volume = volume;
        }

        public int GetVolume()
        {
            return volume;
        }

        public void IncreaseVolume(int amount)
        {
            volume += amount;
        }
    }
}
like image 883
seeker Avatar asked Feb 14 '13 15:02

seeker


People also ask

Can struct values be changed?

Unlike classes, a constant struct's properties cannot be changed—not from outside the struct, not even from within the struct's own methods, even if they're marked as mutating . Once a struct is constant, it is constant. It can't change.

Can struct have default value?

For variables of class types and other reference types, this default value is null . However, since structs are value types that cannot be null , the default value of a struct is the value produced by setting all value type fields to their default value and all reference type fields to null .

Can struct and variable have same name?

This question already has an answer here:Yes, that is perfectly fine.

Can a struct hold functions?

Can C++ struct have member functions? Yes, they can.


2 Answers

Casting a value type (struct) to an interface boxes the value. So you're invoking the method on the boxed copy of the value, not on the value itself.

like image 152
dtb Avatar answered Oct 13 '22 20:10

dtb


Value types (struct) are passed around by value, but interfaces are considered to be reference types (not value types). Let's see:

Bus b = new Bus(1000);

Now b contains the value of a Bus with its volume set to 1000.

Car c = (Car)b;

Now the value in b is copied and made into a reference type (boxed) of Car. Now c contains a pointer to the boxed copy.

c.IncreaseVolume(50);

On the reference type, you call IncreaseVolume, which is a member of the Car interface. It receives the reference to the boxed value. It takes a managed pointer to the value in the box (to make it a value type again).

void Car.IncreaseVolume(int amount)
{
    ((Bus)this).IncreaseVolume(amount);
}

Now your method will act on the value in the box:

public void IncreaseVolume(int amount)
{
    volume += amount;
}

Now the method returns. Notice how no operation ever acted on the value in b, only on copies of it. So the next statement will print 1000:

Console.WriteLine(b.GetVolume());

That's it.

like image 38
Daniel A.A. Pelsmaeker Avatar answered Oct 13 '22 19:10

Daniel A.A. Pelsmaeker