【问题标题】:Accidental Object Reference [duplicate]意外对象参考 [重复]
【发布时间】:2021-02-24 03:20:50
【问题描述】:

我正在做我的一个项目,但当时我没有按预期工作,现在我正在重新评估我的整个人。取下面的类和方法:

public class Test{
     public string Name { get; set; }
     public int Value { get; set; }
}
public Test ReturnExample(Test test)
{
     Test example = test;
     example.Name = "abc";
     return example;
}

现在,如果我有 FirstValueSecondValue

Test FirstValue = new Test {Name = "First", Value = 8 };
Test SecondValue = new Test {Name = "Second", Value = 12 };

到目前为止,一切似乎都非常通用和简单,但让我感到惊讶的是,当你这样做时:

SecondValue = ReturnExample(FirstValue);

我期望的值是:

    FirstValue:
       Name = "First"
       Value = 8
    SecondValue:
       Name = "abc"
       Value = 8

然而,我得到的是:

    FirstValue:
       Name = "abc"
       Value = 8
    SecondValue:
       Name = "abc"
       Value = 8

那么,这里发生了什么,我可以改变什么来得到我想要的?

【问题讨论】:

  • 开始阅读参考值。
  • 旁注:通常将所有涉及的代码内联到单个方法中将是您应该能够自己做的解释......但是由于您对如何传递参数有疑问我不认为你可以做到这一点......希望@SalahAkbari 评论+答案和规范副本可以澄清事情。
  • 你在说什么?你在我接受答案后发表了评论,所以我不清楚你想说的是

标签: c# oop methods reference


【解决方案1】:

基于this

引用类型由持有引用的引用使用 (地址)到对象,而不是对象本身。因为参考 类型代表变量的地址而不是数据 本身,将引用变量分配给另一个不会复制 数据。相反,它会创建引用的第二个副本,它引用 到与原始值相同的堆位置。参考类型 变量存储在称为堆的不同内存区域中。 这意味着当不再使用引用类型变量时,它 可以标记为垃圾回收。

话虽如此,如果您希望代码按预期工作,则需要进行深层复制:

public Test ReturnExample(Test test)
{
    Test example = new Test();
    example.Name = "abc";
    example.Value = test.Value;
    return example;
}

【讨论】:

  • 对于更复杂的类型,比如我的程序中的那个,逐个值做会很笨重,有没有办法简单地深度复制更复杂的类型?
  • @Bubinga 当然,您可以为此目的使用 AutoMapper 之类的工具。这是一个例子:stackoverflow.com/a/39515990/2946329
猜你喜欢
  • 2011-01-21
  • 2018-02-11
  • 2012-09-23
  • 2018-08-22
  • 1970-01-01
  • 1970-01-01
  • 2018-01-30
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多