更改C#字典中项的基数

更改C#字典中项的基数,c#,dictionary,cardinality,C#,Dictionary,Cardinality,我有一本字典,差不多 Dictionary<Foo,String> fooDict 它按照foo添加到字典的顺序执行,因此添加的第一项就是返回的第一个foo 我如何更改基数,例如,添加的第三个foo将是返回的第二个foo?换句话说,我想更改它的“索引”。我在该领域没有受过充分的教育,无法正确回答这个问题,但我有一种感觉,字典根据键对值进行排序,以便执行快速键搜索。这表明字典是根据关键字比较按关键字值排序的。但是,在查看object方法时,我假设它们使用哈希代码来比较不同的对象,因为

我有一本字典,差不多

Dictionary<Foo,String> fooDict
它按照foo添加到字典的顺序执行,因此添加的第一项就是返回的第一个foo

我如何更改基数,例如,添加的第三个foo将是返回的第二个foo?换句话说,我想更改它的“索引”。

我在该领域没有受过充分的教育,无法正确回答这个问题,但我有一种感觉,字典根据键对值进行排序,以便执行快速键搜索。这表明字典是根据关键字比较按关键字值排序的。但是,在查看object方法时,我假设它们使用哈希代码来比较不同的对象,因为对键使用的类型没有要求。这只是猜测。应该由更有知识的人填写更多的细节


当字典的“索引”用于索引任意类型时,您为什么对它感兴趣?

如果您阅读了MSDN上的文档,您会看到:

“返回项目的顺序未定义。”


因为字典不是一个列表或数组,所以不能计算顺序。这意味着通过键查找值,任何迭代值的功能都只是一种方便,但顺序不是您应该依赖的行为。

我不知道是否有人会发现这一点有用,但我最终得出了以下结论。它似乎可以工作(我的意思是它不会抛出任何异常),但我离测试它是否能像我希望的那样工作还有很长的路要走。不过,我以前也做过类似的事情

        public void sortSections()
    {
        //OMG THIS IS UGLY!!!
        KeyValuePair<ListViewItem, TextSection>[] sortable = textSecs.ToArray();
        IOrderedEnumerable<KeyValuePair<ListViewItem, TextSection>> sorted = sortable.OrderBy(kvp => kvp.Value.cardinality);

        foreach (KeyValuePair<ListViewItem, TextSection> kvp in sorted)
        {
            TextSection sec = kvp.Value;
            ListViewItem key = kvp.Key;

            textSecs.Remove(key);
            textSecs.Add(key, sec);
        }
    }
public void排序操作()
{
//天哪,这太难看了!!!
KeyValuePair[]sortable=textSecs.ToArray();
IOrderedEnumerable sorted=sortable.OrderBy(kvp=>kvp.Value.cardinality);
foreach(排序中的KeyValuePair kvp)
{
TextSection sec=kvp.值;
ListViewItem key=kvp.key;
textSecs.Remove(键);
textSecs.Add(键,秒);
}
}

简单的回答是,不应该有任何方法,因为字典“代表键和值的集合”。这并不意味着任何排序。您可能发现的任何黑客行为都超出了类的定义,并且可能会发生更改

您可能首先应该问问自己,在这种情况下是否真的需要词典,或者是否可以使用KeyValuePairs列表

否则,类似这样的内容可能会有用:

public class IndexableDictionary<T1, T2> : Dictionary<T1, T2>
{
    private SortedDictionary<int, T1> _sortedKeys;

    public IndexableDictionary()
    {
        _sortedKeys = new SortedDictionary<int, T1>();
    }
    public new void Add(T1 key, T2 value)
    {
        _sortedKeys.Add(_sortedKeys.Count + 1, key);
        base.Add(key, value);
    }

    private IEnumerable<KeyValuePair<T1, T2>> Enumerable()
    {
        foreach (T1 key in _sortedKeys.Values)
        {
            yield return new KeyValuePair<T1, T2>(key, this[key]);
        }
    }

    public new IEnumerator<KeyValuePair<T1, T2>> GetEnumerator()
    {
        return Enumerable().GetEnumerator();
    }

    public KeyValuePair<T1, T2> this[int index]
    {
        get
        {
            return new KeyValuePair<T1, T2> (_sortedKeys[index], base[_sortedKeys[index]]);
        }
        set
        {
            _sortedKeys[index] = value.Key;
            base[value.Key] = value.Value;
        }

    }


}
公共类索引字典:字典
{
私人分类词典;
公共索引字典()
{
_sortedKeys=新的SortedDictionary();
}
公共新空添加(T1键,T2值)
{
_sortedKeys.Add(_sortedKeys.Count+1,键);
添加(键、值);
}
私有IEnumerable可枚举()
{
foreach(T1输入值)
{
返回新的KeyValuePair(key,this[key]);
}
}
公共新IEnumerator GetEnumerator()
{
返回Enumerable().GetEnumerator();
}
public KeyValuePair this[int index]
{
得到
{
返回新的KeyValuePair(_-sortedKeys[index],base[_-sortedKeys[index]);
}
设置
{
_sortedKeys[索引]=value.Key;
base[value.Key]=value.value;
}
}
}
客户端代码如下所示:

    static void Main(string[] args)
    {
        IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();

        fooDict.Add("One", "One");
        fooDict.Add("Two", "Two");
        fooDict.Add("Three", "Three");

        // Print One, Two, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);



        KeyValuePair<string, string> temp = fooDict[1];
        fooDict[1] = fooDict[2];
        fooDict[2] = temp;


        // Print Two, One, Three
        foreach (KeyValuePair<string, string> kvp in fooDict)
            Console.WriteLine(kvp.Value);

        Console.ReadLine();
    }
static void Main(字符串[]args)
{
IndexableDictionary fooDict=新的IndexableDictionary();
添加(“一”、“一”);
添加(“两个”、“两个”);
添加(“三”、“三”);
//打印一,二,三
foreach(fooDict中的KeyValuePair kvp)
控制台写入线(kvp.Value);
KeyValuePair temp=fooDict[1];
fooDict[1]=fooDict[2];
fooDict[2]=温度;
//打印二,一,三
foreach(fooDict中的KeyValuePair kvp)
控制台写入线(kvp.Value);
Console.ReadLine();
}
更新:出于某种原因,它不会让我对自己的答案发表评论

无论如何,IndexableDictionary与OrderedDictionary的不同之处在于

  • “OrderedDictionary的元素没有以任何方式进行排序。”因此foreach不会关注数字索引
  • 它是强类型的,因此您不必费劲地从DictionaryEntry结构中排除内容

  • 您可能对命名空间中的类感兴趣

    如果你看看最下面的评论,MSFT的某个人发布了一条有趣的留言:

    这种类型实际上命名错误;它本身不是一个“有序”词典,而是一个“索引”词典。尽管目前还没有这种类型的等效泛型版本,但如果将来添加一个,我们很可能会将其命名为“IndexedDictionary”类型


    我认为从这个类派生并生成OrderedDictionary的泛型版本是很简单的。

    我的字典实际上是字典,我想这样做,当用户在listview中重新排序项目时,它也会重新排序字典中的项目,以便它们以相同的顺序出现。您“可能”很好,但就像我说的,订购是不能保证的。我打赌在它需要调整大小的那一刻,它将在尝试中重新排序所有内容。为什么还要使用字典?希望将listviewitem与自定义对象关联。在我正在进行的项目中,我已经做过几次了,但这是第一次基数真正重要。尽管.NET中有一个替代对象允许您在Diicationary中维护顺序,请参见:这不是本质上重新创建OrderedDictionary吗?@spoon16:它是强类型的(装箱/拆箱性能不会降低
        static void Main(string[] args)
        {
            IndexableDictionary<string, string> fooDict = new IndexableDictionary<string, string>();
    
            fooDict.Add("One", "One");
            fooDict.Add("Two", "Two");
            fooDict.Add("Three", "Three");
    
            // Print One, Two, Three
            foreach (KeyValuePair<string, string> kvp in fooDict)
                Console.WriteLine(kvp.Value);
    
    
    
            KeyValuePair<string, string> temp = fooDict[1];
            fooDict[1] = fooDict[2];
            fooDict[2] = temp;
    
    
            // Print Two, One, Three
            foreach (KeyValuePair<string, string> kvp in fooDict)
                Console.WriteLine(kvp.Value);
    
            Console.ReadLine();
        }