传递ref关键字

本文关键字:关键字 ref 传递 | 更新日期: 2023-09-27 17:51:19

我有两个标签页(tabA和tabB)在一个主要的形式。假设我将tabA传递到tabB的主要形式初始化:

tabB = new TabB(tabA);

所以我观察到的是,在改变了tabA(比如tabA.Text)内部的值之后,tabB (tabB.tabA.Text)内部的值也发生了变化。

所以我的理解(来自c++)是,这类似于引用传递。我的问题是如果我把它写成这样会有什么不同?

tabB = new TabB(ref tabA);

传递ref关键字

你对c++的类比是不正确的。在c#中传递引用对象*类似于在c++中通过指针传递对象,不同之处是c#不需要星号来取消对这些指针的引用。

c#中的引用传递类似于c++中的引用传递:除了在函数中使用该指针外,还可以为其赋一个新值,从而改变调用者中指针的值。

下面是一个简短的说明:

void One(List<int> list) {
    // Reassignment of the list is local to method One
    list = new List<int> {1, 2, 3};
}
void Two(ref List<int> list) {
    // Reassignment of the list is visible in the caller
    list = new List<int> {1, 2, 3};
}
...
var demo = new List<int> {5, 6, 7};
One(demo);
// Here the list remains [5, 6, 7]
Two(ref demo);
// Here the list becomes [1, 2, 3]

*相对于值对象,如 structs和原语,它们被复制。

区别在于,如果您在TabB构造函数中通过tabA参数更改了指向的对象,tabA也将使用新对象。

实际上没有传递对象本身的方法,但是你可以做一个复制/克隆,看起来就像原来的一样。对于复制windows控件的一般情况,已经编写了一个很好的答案,并且仅针对选项卡的答案。

不同之处在于,通过使用ref关键字,您可以更改引用本身,而不仅仅是引用所指向的对象。

void funcA(TabA tabA)
{
   // setting tabA to null here has no effect outside this function
   tabA = null;
}
void funcB(ref TabA tabA)
{
   // setting tabA to null persists outside this function
   // and changes the actual reference passed in.
   tabA = null;
}
// tabA initialized to non-null
tabA = new TabA();
funcA(tabA);
// tabA is still not null
funcB(ref tabA);
// tabA is now null