通用交换难度

10

我来自C++,在那里做这样的事情很容易:

template<class T>
void Swap(T &a, T &b)
{
  T temp = a;
  a = b;
  b = temp;
}

然后,您可以使用它来交换容器中的值:
std::vector<int> someInts;
someInts.push_back(1);
someInts.push_back(2);

Swap(someInts[0], someInts[1]);

然而,在尝试使用C#执行相同操作时,
void Swap<T>(ref T a, ref T b)
{
        T temp = a;
    a = b;
    b = temp;
}

我遇到了“属性或索引器不能作为 out 或 ref 参数传递”的错误。为什么会出现这个错误,我该如何克服它呢?非常感谢。

属性和索引器被引入是为了方便使用它们,就像它们是值一样(即使在底层它们是多个方法),但这也是我不喜欢它们的原因之一。至少,应该有一些方法使您想要做的事情起作用,但目前大多数新语言在这一点上都很糟糕。 - comco
2个回答

2

您不能使用索引器或属性的ref参数。原因是返回的是对象的引用而不是位置,所以函数产生的任何影响都不会实际改变源代码,因为它不会将其写回到位置(即在属性的情况下不会调用setter)。你需要将数组传递到方法中,这样方法就可以设置值和索引,还可以知道要交换的值。


0

属性和索引器实际上是方法(由编译器在幕后创建),因此我认为无法对它们进行按引用调用。但是,您可以编写以下方法:

public void Swap<T>(T[] data, int a, int b) {
  T temp = data[a];
  data[a] = data[b];
  data[b] = temp;
}

Swap(someInts, 0, 1);

是的,我知道,但感觉像是一个hack。:( 谢谢。 - mat
1
根据 MSDN 的信息,C# 中的数组似乎不是使用指针的某种类型结构(在不安全上下文中也存在这种情况),但数组是从 System.Array 派生出来的,因此没有 "快速/直接访问"。为了使您的代码更清晰,您可以将该代码包装到扩展方法中,这样它会更易读。 - jCoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接