2011-04-16 68 views
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参数传递“

这是为什么,我该如何克服它?

非常感谢

+0

属性和索引都介绍了,如果他们的值(即使在引擎盖下他们是多种方法),方便使用它们,但这是原因之一我不喜欢他们。至少,应该有某种方式让你想要做什么工作,但是目前,大多数新语言都在这一点上吸引人。 – comco 2013-12-15 22:31:25

回答

2

您不能使用索引器或属性参考参数。原因是你正在重新调用对象的引用而不是位置,所以任何影响函数的内容都不会实际改变源文件,因为它不会将它写回到位置(即在没有调用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); 
+0

是的,我知道,但它感觉像一个黑客。 :(谢谢。 – mat 2011-04-16 14:48:15

+1

根据MSDN提供的信息,它看起来像C#中的数组不是某种使用指针的结构(这种情况也存在于不安全的上下文中),但是数组是从System.Array派生的,因此没有“快速/直接访问“为了让你的代码更清洁,你可以将代码包装到扩展方法中,使其更具可读性。 – jCoder 2011-04-16 15:21:28