通过引用传递对象
Passing an object by reference
我已经阅读了很多这方面的内容,但我认为这只会让我更加困惑。为了解决这个问题,我想做的是:
public sealed partial class MainPage : Page
{
MyFirstDataType Object1 = new MyFirstDataType();
MySecondDataType Object2;
void Button_Click_Event_Handler(Object sender, RoutedEventArgs e)
{
Object2 = new MySecondDataType(Object1);
Object2.DoSomethingUseful();
}
}
现在在 MySecondDataType
的定义中:
public class MySecondDataType
{
MyFirstDataType MyObject;
internal MySecondDataType(MyFirstDataType arg)
{
MyObject = arg;
}
public void DoSomethingUseful()
{
//modify MyObject in some way
}
}
所以基本上我已经将一个对象传递给另一个 class 的构造函数,其中我 "copy" 将对象传递给那个 class 的内部数据成员。我想要的是每次 DoSomethingUseful()
函数执行时,它对 MyObject
所做的更改应该反映在我主页上的原始 Object1
中。
根据我目前所读到的内容,如果我像 arg.counter = 1
那样简单地修改构造函数中传递的对象,更改也会反映在原始对象中,但是当我write MyObject = arg;
这会创建一个独立于原始对象的单独副本。我该如何解决这个问题?还是我对通过引用传递的理解有缺陷? (我有预感是)。
where I "copy" the object to an internal data member of that class
好吧,那是个错误。传递的对象不会被复制。他们的引用被复制。如果您现在调用 MyObject.SomeVar = 1
,原始对象的 SomeVar
也会改变,因为只有一个对象。
重置 MyObject = SomethingElse
会将两者分离,您对 MyObject
的更改将不会反映在第一个对象中。
C# 编程指南中有一篇很好的读物:Passing Reference-Type Parameters。
作为后续:string
是一个引用类型,即 immutable。你无法改变它,永远。即使在同一范围内有两个变量时也不例外。您可以使用包装器 class 来包装 string
,这使得传递更容易。
public class Wrapper<T>
{
public T Value {get;set;}
}
internal MySecondDataType(Wrapper<MyFirstDataType> arg) { }
你可以设置值:
arg.Value = ...;
然后这样称呼它:
var w = new Wrapper<MyFirstDataType>(Variable1);
Object2 = new MySecondDataType(w);
然后使用包装器 class 中更新的 Value
。
没有复制。使用 new
运算符进行引用。您正在将此对象传递给 SecondDataType
。两者指的是同一个对象。
即使您将 MyFirstDataType class 对象传递给 MySecondDataType 的构造函数,它的副本也是您传递的对象引用的副本,而不是对象本身的副本。本质上是它的创建参考副本。
也许这个例子会帮助你理解它。
public class A
{
int count=0;
public void Increment()
{
count++;
}
}
public class B
{
A a;
public B(A a)
{
this.a = a;
}
}
然后
private void button2_Click(object sender, EventArgs e)
{
A a = new A();
B b = new B(a);
a.Increment(); //Increment count of a
//If you check value of count of a in b after above line it should be 1.
}
我认为您对按引用传递的理解大致正确。阅读您的问题,我相信在您的示例中,您在示例中提供的更新应该有效。正如其他答案中所指定的,您实际上是在复制指向第一个对象的指针,因此该对象本质上是相同的。
我的猜测是当你说:
the changes it makes to MyObject should reflect in the original
Object1 on my main page.
您没有实施 INotifyPropertyChanged 或等效物。
我已经阅读了很多这方面的内容,但我认为这只会让我更加困惑。为了解决这个问题,我想做的是:
public sealed partial class MainPage : Page
{
MyFirstDataType Object1 = new MyFirstDataType();
MySecondDataType Object2;
void Button_Click_Event_Handler(Object sender, RoutedEventArgs e)
{
Object2 = new MySecondDataType(Object1);
Object2.DoSomethingUseful();
}
}
现在在 MySecondDataType
的定义中:
public class MySecondDataType
{
MyFirstDataType MyObject;
internal MySecondDataType(MyFirstDataType arg)
{
MyObject = arg;
}
public void DoSomethingUseful()
{
//modify MyObject in some way
}
}
所以基本上我已经将一个对象传递给另一个 class 的构造函数,其中我 "copy" 将对象传递给那个 class 的内部数据成员。我想要的是每次 DoSomethingUseful()
函数执行时,它对 MyObject
所做的更改应该反映在我主页上的原始 Object1
中。
根据我目前所读到的内容,如果我像 arg.counter = 1
那样简单地修改构造函数中传递的对象,更改也会反映在原始对象中,但是当我write MyObject = arg;
这会创建一个独立于原始对象的单独副本。我该如何解决这个问题?还是我对通过引用传递的理解有缺陷? (我有预感是)。
where I "copy" the object to an internal data member of that class
好吧,那是个错误。传递的对象不会被复制。他们的引用被复制。如果您现在调用 MyObject.SomeVar = 1
,原始对象的 SomeVar
也会改变,因为只有一个对象。
重置 MyObject = SomethingElse
会将两者分离,您对 MyObject
的更改将不会反映在第一个对象中。
C# 编程指南中有一篇很好的读物:Passing Reference-Type Parameters。
作为后续:string
是一个引用类型,即 immutable。你无法改变它,永远。即使在同一范围内有两个变量时也不例外。您可以使用包装器 class 来包装 string
,这使得传递更容易。
public class Wrapper<T>
{
public T Value {get;set;}
}
internal MySecondDataType(Wrapper<MyFirstDataType> arg) { }
你可以设置值:
arg.Value = ...;
然后这样称呼它:
var w = new Wrapper<MyFirstDataType>(Variable1);
Object2 = new MySecondDataType(w);
然后使用包装器 class 中更新的 Value
。
没有复制。使用 new
运算符进行引用。您正在将此对象传递给 SecondDataType
。两者指的是同一个对象。
即使您将 MyFirstDataType class 对象传递给 MySecondDataType 的构造函数,它的副本也是您传递的对象引用的副本,而不是对象本身的副本。本质上是它的创建参考副本。 也许这个例子会帮助你理解它。
public class A
{
int count=0;
public void Increment()
{
count++;
}
}
public class B
{
A a;
public B(A a)
{
this.a = a;
}
}
然后
private void button2_Click(object sender, EventArgs e)
{
A a = new A();
B b = new B(a);
a.Increment(); //Increment count of a
//If you check value of count of a in b after above line it should be 1.
}
我认为您对按引用传递的理解大致正确。阅读您的问题,我相信在您的示例中,您在示例中提供的更新应该有效。正如其他答案中所指定的,您实际上是在复制指向第一个对象的指针,因此该对象本质上是相同的。
我的猜测是当你说:
the changes it makes to MyObject should reflect in the original Object1 on my main page.
您没有实施 INotifyPropertyChanged 或等效物。