C# - 通过指针不安全地交换字典值

时间:2017-05-21 22:59:35

标签: c# performance pointers dictionary unsafe

我有两组词典,每组都包含相同的键并具有初始值。

使用不安全的代码,我想交换他们的地址:

Dictionary<string, List<object>> d1 = ...
Dictionary<string, List<object>> d2 = ...
unsafe void SwapEntries(string index)
{
    int* tmp = &d1[index];
    &d1[index] = &d2[index]
    &d2[index] = tmp;
}

假设我已经正确地调用了我的指针运算,我正在寻找的输出将是:

d1 = new Dictionary<string, List<int>>() { "a", { 1, 2, 3 } };
d2 = new Dictionary<string, List<int>>() { "a", { 4, 5, 6 } };
SwapEntries("a");
Console.WriteLine(d1["a"]); //4,5,6
Console.WriteLine(d2["a"]); //1,2,3

然而,当我尝试写这个时,我得到编译错误“无法获取给定表达式的地址。”

1)有没有更快的方法来执行我错过的地址交换?性能是这里唯一的优先事项。

2)我的指针算术是否正确?

3)我是否需要完全转移到包装器或不同的数据结构,以便能够按照描述执行地址交换?

2 个答案:

答案 0 :(得分:2)

我同意Martin Ullrich的回答。

表达式d1[index]不是变量。它是get定义的索引器的Dictionary<,>访问器的调用。您无法使用&运算符指向该指针。

此外,在这种情况下,它的类型是List<object>。您只能指向值类型,List<>class类型。

即使您确实拥有真正的存储位置,并且它的类型为object[],但由于数组的元素类型为object,因此仍然无法实现。因此,arr[0](对应d1[index][0])将再次成为class类型,您无法获取该地址。

Scott Chamberlain对您的问题的评论给出了一个简单的方法。只需使用

void SwapEntries(string index) 
{
    var tmp = d1[index];
    d1[index] = d2[index];
    d2[index] = tmp; 
}

这只涉及将引用传递给相关的两个List<object>个实例。

答案 1 :(得分:1)

不支持自动指向字典成员的指针 - 它们仅适用于使用C#7&#34; ref return&#34;的数组或数据类型。索引器,属性或方法的功能。