堆栈覆盖先前的推送C#

时间:2015-03-19 20:01:08

标签: c# stack

我在使用Stack<>对象时遇到问题。 push()方法将覆盖Stack对象中堆叠的所有先前值。这是我的示例代码:

Vehicle veh = new Vehicle();
Stack<Vehicle> StackVeh = new Stack<Vehicle>();

StackVeh.Clear();

veh.Class = "A";
veh.Speed = 280;
veh.Active = true;
StackVeh.Push(veh);

veh.Class = "C";
veh.Speed = 200;
veh.Active = false;
StackVeh.Push(veh);

veh.Class = "B";
veh.Speed = 160;
veh.Active = true;
StackVeh.Push(veh);

veh.Class = "AAA";
veh.Speed = 320;
veh.Active = false;
StackVeh.Push(veh);

foreach (Vehicle v in StackVeh)
{
   Console.WriteLine("\n");
   Console.WriteLine(v.Class);
   Console.WriteLine(v.Speed);
   Console.WriteLine(v.Active);
}

我在控制台中的结果是:

> AAA
> 320
> False
> 
> AAA
> 320
> False
>
> AAA
> 320
> False
>
> AAA
> 320
> False

我在这里做错了什么????

2 个答案:

答案 0 :(得分:3)

问题永远不会new你的车辆实例。发生的事情是车辆的一个实例被推入堆栈然后被修改,然后再次添加。最终结果是对引入堆栈的同一对象的4个引用,最终形式为

veh.Class = "AAA";
veh.Speed = 320;
veh.Active = false;

您的代码应为以下

Vehicle veh = new Vehicle();
Stack<Vehicle> StackVeh = new Stack<Vehicle>();

StackVeh.Clear();

veh.Class = "A";
veh.Speed = 280;
veh.Active = true;
StackVeh.Push(veh);

veh = new Vehicle();

veh.Class = "C";
veh.Speed = 200;
veh.Active = false;
StackVeh.Push(veh);

veh = new Vehicle();

veh.Class = "B";
veh.Speed = 160;
veh.Active = true;
StackVeh.Push(veh);

veh = new Vehicle();

veh.Class = "AAA";
veh.Speed = 320;
veh.Active = false;
StackVeh.Push(veh);

foreach (Vehicle v in StackVeh)
{
   Console.WriteLine("\n");
   Console.WriteLine(v.Class);
   Console.WriteLine(v.Speed);
   Console.WriteLine(v.Active);
}

这将确保您使用Vehicle的新实例,而不是为单个实例分配新值。

答案 1 :(得分:0)

您需要将veh设置为新的Vehicle,因为您正在传递对象引用。推送不会覆盖任何东西,事实上你不断更新同一个对象而不是创建新对象......

您的创作代码也可以简化一点:

var vehicles = new Stack<Vehicle>();

var veh = new Vehicle {Class = "A", Speed = 280, Active = true};
vehicles.Push(veh);

veh = new Vehicle {Class = "C", Speed = 200, Active = false};
vehicles.Push(veh);

veh = new Vehicle {Class = "B", Speed = 160, Active = true};
vehicles.Push(veh);

veh = new Vehicle {Class = "AAA", Speed = 320, Active = false};
vehicles.Push(veh);

foreach (var vehicle in vehicles)
{
    Console.WriteLine();
    Console.WriteLine(vehicle.Class);
    Console.WriteLine(vehicle.Speed);
    Console.WriteLine(vehicle.Active);
}

事实上,你甚至根本不需要veh变量,你可以直接推新车,将你的代码从最初的20行减少到5:

var vehicles = new Stack<Vehicle>();
vehicles.Push(new Vehicle {Class = "A", Speed = 280, Active = true});
vehicles.Push(new Vehicle {Class = "C", Speed = 200, Active = false});
vehicles.Push(new Vehicle {Class = "B", Speed = 160, Active = true});
vehicles.Push(new Vehicle {Class = "AAA", Speed = 320, Active = false});

您也可以考虑覆盖ToString()课程中的Vehicle方法:

class Vehicle
{
    public string Class { get; set; }
    public int Speed { get; set; }
    public bool Active { get; set; }

    public override string ToString()
    {
        return string.Format("Class: {0}, Speed: {1}, Active: {2}", 
            Class, Speed, Active);
    }
}

这样你就可以做类似的事情:

for (int i = 0; i < vehicles.Count; i++)
{
    Console.WriteLine("Vehicle #{0} properties: {1}", i + 1, vehicles.ElementAt(i));
}