我正在使用一个框架,该框架通过值在类之间传递对象,我需要更新对其中一个对象的引用。我可以可以更改原始对象的属性值,但是我似乎无法弄清楚如何更改对一个全新对象的引用。在后者的一个类中,我是从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();
}
您正在使用内部本地函数中的ref
关键字,但在外部函数中不使用。另外,如果意图实际上是 swap 参考文献,则该方法不这样做。
public void SwapPersonFour(Person newPerson)
{
LocalSwap(ref person, ref newPerson);
void LocalSwap(ref Person oldPerson, ref Person _newPerson)
{
oldPerson = _newPerson;
}
}
oldPerson
和 _newPerson
通过参考传递给本地函数,但 newPerson
按值传递给 SwapPersonFour
。
另外,仅更新oldPerson
,因此现在oldPerson
和_newPerson
都请参考同一Person
。
如果要更新传递给SwapPersonFour
的引用,则还必须使用ref
关键字来传递该参数。
public void SwapPersonFour(ref Person newPerson)
评论提到它不起作用,所以我整理了一个仓促的单位测试,看看我是否缺少某些东西。(我一直都想念东西,这就是我编写单元测试的原因。(
[TestClass]
public class UnitTest1
{
private Person _person;
[TestMethod]
public void TestSwappingPerson()
{
_person = new Person { FirstName = "Scott" };
var newPerson = new Person() { FirstName = "Bob" };
SwapPersonFour(ref newPerson);
Assert.AreEqual("Bob", _person.FirstName);
}
public void SwapPersonFour(ref Person newPerson)
{
LocalSwap(ref _person, ref newPerson);
void LocalSwap(ref Person oldPerson, ref Person localNewPerson)
{
oldPerson = localNewPerson;
}
}
}
SwapPersonFour
用newPerson
的引用替换_person
字段。它实际上并没有交换任何内容,因为当它更新_person
时,它没有更新newPerson
。完成后,它们都是同一Person
的引用。(您是要交换它们吗?这可能是问题。(
对于它的价值,我会删除本地功能,因为它实际上没有做任何事情。它只需要该方法做的一件事,然后将其嵌套在额外的功能中。您可以用它替换它并获得相同的结果 - 它更容易阅读。(实际上,额外的代码可能会让您更容易错过任何东西。
public void SwapPersonFour(ref Person newPerson)
{
_person = newPerson;
}
如果您实际上想交换它们,则可以这样做:
public void SwapPersonFour(ref Person newPerson)
{
var temp = _person;
_person = newPerson;
newPerson = temp;
}