交换数组中的对象 - C#

问题描述 投票:3回答:7

在C#中,我有一个MenuItem数组。我正在尝试使用下面的代码交换数组的索引2和索引3中的两个对象,但没有成功:

MenuItem Temp = Items[2];  
Items[2] = Items[3];  
Items[3] = Temp;  

必须有一个原因,为什么第二行和第三行不能在C#中工作,我可能还不明白。有人能够澄清一点吗?我是否必须更深入地分别交换对象中的每个属性?

编辑 - 抱歉。看起来我试图清理它以便发布时弄乱了代码。现在更正了。

实际代码是:

MenuItem TempButton = MenuItems.Items[SelectedButton.CountId];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[SelectedButton.CountId + 1];  
MenuItems.Items[SelectedButton.CountId + 1] = TempButton;  

MenuItems.Items是一系列MenuItem

看看我放在MenuItems.Items上的Watch,第2行或第3行没有任何反应。

MenuItems.Items属性具有获取和设置功能,这可能导致问题......将进一步调查......

c# arrays object swap
7个回答
3
投票

你是设置Items[2]Temp,这是Items[2]开始,所以你实际上没有做任何事情。我不知道SelectedButton.CountId应该是什么。

但是如果你只想交换索引2和3,你可以这样做:

Item Temp = Items[2];
Items[2] = Items[3];
Items[3] = Temp;

1
投票

SelectedButton.CountId = 2?如果是这样我会试试这个:

Item Temp = MenuItems.Items[2];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[3];  
MenuItems.Items[3] = Temp;  

注意最后一行有3个。

这会更清楚:

Item Temp = MenuItems.Items[SelectedButton.CountId];  
MenuItems.Items[SelectedButton.CountId] = MenuItems.Items[3];  
MenuItems.Items[3] = Temp;  

1
投票

我不知道SelectedButton.CountId应该是什么,但是你把Temp放回到它开始的同一个插槽中。 MenuItems.Items似乎与Items完全不同。

string[] items = { "one", "two", "three" };
string temp = items[1]; // temp = "two"
items[1] = items[2]; // items[1] = "three"
items[2] = temp; // items[2] = "two"

// items is now
// { "one", "three", "two" }

1
投票

尝试:

Item Temp = Items[SelectedButton.CountId];   
Items[SelectedButton.CountId] = MenuItems.Items[SelectedButton.CountId+1];   
Items[SelectedButton.CountId+1] = Temp;  

这应该以泡沫方式交换


1
投票

我记得前一段时间遇到类似的混乱,使用DataRow.ItemArray属性。这个属性非常违反直觉,因为你的例子中的Items属性看起来很奇怪。

最终令人困惑的是,该属性被设计为复制和分配,就像您通常使用值类型的字段(如intdouble等)。也就是说,要更改索引2处的元素,这将不起作用:

row.ItemArray[2] = "New Value";

上面的代码基本上将行中的值复制到一个新数组中,获取该副本并将索引2处的值设置为“New Value”,然后新数组将立即超出范围。这个属性的工作方式是:

object[] items = row.ItemArray;
items[2] = "New Value";
row.ItemArray = items;

非常违反直觉,在我的书中(对库开发人员的说明:不要这样做)。但听起来这可能是您在代码中看到的问题背后的问题。

换句话说,我认为你现在拥有的交换代码是正确的。问题在于谁有明智的想法让Items属性表现得好像它是一个价值领域。


0
投票

我遇到了同样的问题,因为我想在WPF-TreeView中上下移动元素。既然没有一个答案能解决我这里的问题,那就是我能找到的最好的答案。

    private void MoveLayerUp()
    {
        if(Layers.SelectedItem != null)
        {
            int index = Layers.Items.IndexOf(Layers.SelectedItem);
            if (index > 0)
            {
                var swap = Layers.Items[index - 1];
                Layers.Items.RemoveAt(index - 1);
                Layers.Items.Insert(index, swap);
            }
        }
    }

    private void MoveLayerDown()
    {
        if (Layers.SelectedItem != null)
        {
            int index = Layers.Items.IndexOf(Layers.SelectedItem);
            if (index < Layers.Items.Count-1)
            {
                var swap = Layers.Items[index + 1];
                Layers.Items.RemoveAt(index + 1);
                Layers.Items.Insert(index, swap);
            }
        }
    }

这解决了在集合中分配元素的问题。此外,它具有以下优点:永远不会触摸当前所选择的项目并保持选择。


-1
投票

解决了这个问题。我觉得我把这个问题弄得太复杂了。

MenuItems.Items是一个带有get / set函数的属性,它返回/设置一个私有ArrayList。

我在类中为MenuItems创建了一个函数,它交换了私有ArrayList中的索引。 (它使用的标准交换代码类似于我尝试的内容以及每个人在回复中提到的内容。)

谢谢大家的帮助。

© www.soinside.com 2019 - 2024. All rights reserved.