【发布时间】:2019-09-27 04:33:00
【问题描述】:
我正在使用一个按值在类之间传递对象的框架,我需要更新对其中一个对象的引用。我可以很好地更改原始对象的属性值,但我似乎无法弄清楚如何更改对全新对象的引用。在后面的一个类中,我从 API 中检索一个相当复杂的对象,因此我希望只更新引用而不是尝试深度复制。
我尝试在我的代码示例中调用SwapPerson{One,Two,Three,Four},但没有任何成功的迹象。输出总是:
Main.person: Groucho Marx is 128 years old!
Main.person: Groucho Marx is 129 years old!
Main.person: Groucho Marx is 129 years old!
我希望有一个简单的解决方案,由于时间较晚,我忽略了,因此非常感谢任何输入。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public override string ToString()
{
return $"{FirstName} {LastName} is {Age} years old!";
}
}
public class Foo
{
private Person person;
public Foo(Person person)
{
this.person = person;
}
public void SetAge(int age)
{
person.Age = age;
}
public void SwapPersonOne(Person newPerson)
{
person = newPerson;
}
public void SwapPersonTwo(ref Person newPerson)
{
person = newPerson;
}
public void SwapPersonThree(Person newPerson)
{
LocalSwap(ref person);
void LocalSwap(ref Person oldPerson)
{
oldPerson = newPerson;
}
}
public void SwapPersonFour(Person newPerson)
{
LocalSwap(ref person, ref newPerson);
void LocalSwap(ref Person oldPerson, ref Person _newPerson)
{
oldPerson = _newPerson;
}
}
}
static void Main(string[] args)
{
Person person = new Person { FirstName = "Groucho", LastName = "Marx", Age = 128 };
Console.WriteLine($"{nameof(Main)}.{nameof(person)}: {person}");
var foo = new Foo(person);
foo.SetAge(129);
Console.WriteLine($"{nameof(Main)}.{nameof(person)}: {person}");
var charlie = new Person { FirstName = "Charlie", LastName = "Chaplin", Age = 130 };
//foo.SwapPersonOne(charlie);
//foo.SwapPersonTwo(ref charlie);
//foo.SwapPersonThree(charlie);
foo.SwapPersonFour(charlie);
Console.WriteLine($"{nameof(Main)}.{nameof(person)}: {person}");
Console.ReadLine();
}
【问题讨论】:
-
你需要克隆对象,否则你仍然指向同一个内存地址。实现 IClonable。
-
@Fleshy,我正在寻找更新原始对象的引用,我不认为克隆是解决方案。
-
我误解了这个问题。
-
我认为你对
ref在C#中的含义有误解;这令人困惑。它与对对象的引用 没有任何关系。ref在 C# 中被更好地理解为“变量的别名”。当您有一个函数Foo(ref T y)并调用它Foo(ref x)时,这意味着x和y是同一个变量的两个名称;它们是彼此的别名。既然知道ref的意思是“给变量起别名”,是不是你程序的意思就更清楚了? -
特别是,您的
SwapPersonTwo与SwapPersonOne的行为无法区分,因为您从不写入引用变量。如果变量从不写入,则传递变量的值和创建变量的别名在逻辑上是相同的。确保你明白这一点。
标签: c# pass-by-reference variable-assignment pass-by-value ref