【问题标题】:c# Is it possible get a reference of an object, get the object itself and change it, instead of assinging to a new object?c#是否有可能获取对象的引用,获取对象本身并更改它,而不是分配给新对象?
【发布时间】:2013-10-02 20:28:58
【问题描述】:

我只是好奇在 c# 中是否可以实现类似的功能。我不知道为什么会有人想要这样做,但如果能做到这一点仍然很有趣。:

public class Test
{
    public string TestString { private set; get; }
    public Test(string val) { TestString = val; }
}

    public class IsItPossible
    {
        public void IsItPossible()
        {
            Test a = new Test("original");
            var b = a;
            //instead of assigning be to new object, I want to get where b is pointing and change the original object
            b = new Test("Changed"); // this will assign "b" to a new object", "a" will stay the same. We want to change "a" through "b"
            //now they will point to different things
            b.Equals(a); // will be false
            //what I'm curious about is getting where b is pointing and changing the object itself, not making just b to point to a new object
            //obviously, don't touch a, that's the whole point of this challenge

            b = a;
            //some magic function
            ReplaceOriginalObject(b, new Test("Changed"));
            if (a.TestString == "Changed" && a.Equals(b)) Console.WriteLine("Success");
        }
    }

【问题讨论】:

  • 我不这么认为,尽管我认为这也不重要。当您创建新对象并将变量指向新对象(堆上的新空间)时,如果没有任何东西引用旧对象(堆上的旧空间),那么垃圾收集器将迅速摆脱它,留下你在逻辑上等于你想要达到的状态。
  • 在线b = new Test("Changed"); 你说“//这会将“b”分配给一个新对象”,从技术上讲,您应该说“//这会将一个新对象分配给“b”`
  • 创建新对象是条件之一吗?如果不是,b = a;后面跟着 b.TestString = "Changed" 会改变对象的值。虽然你只有一个。
  • @alvaro 是的。它想替换对象本身,而不仅仅是它的部分。
  • @CoolCodeBro 那么,这是不可能的。 C# 不允许你改变这种指针

标签: c# object reference assign


【解决方案1】:

如果您的意思是“我可以通过更改 b 的值来更改 a 的值以引用不同的对象吗?”那么答案是否定的。

重要的是要理解变量的值永远不是对象 - 始终是值类型值或引用。我喜欢把变量想象成纸片,把物体想象成房子。

一张纸上可以写有值类型的值(例如数字)或房子的地址。当你写:

var b = a;

这是创建一张新纸 (b) 并将写在纸 a 上的内容复制到纸 b 上。此时您可以做两件事:

  • 更改b 上的内容。这不会影响a 上的内容,即使是切线
  • 前往b 上写的地址,修改房屋(例如粉刷前门)。这也不会改变写在a 上的内容,但它确实意味着当您访问写在a 上的地址时,您会看到更改(因为您将访问相同的地址)房子)。

这是假设“常规”变量,请注意 - 如果您使用 ref 参数,您实际上是在使一个变量成为另一个变量的别名。比如:

Test a = new Test("Original");
ChangeMe(ref a);
Conosole.WriteLine(a.TestString); // Changed

...

static void ChangeMe(ref Test b)
{
    b = new Test("Changed"); // This will change the value of a!
}

这里我们实际上有一张纸,名称为a(在调用代码中)b(在方法中)。

【讨论】:

  • 是的,a 是参考,b 是参考。我想获取该引用指向的位置并在 c# 中更改它
  • @CoolCodeBro:不,a 是一个变量,b 是一个变量。它们的是引用。
  • 好的,A 上面写着房子的地址。 B 复制 a 中的内容。 B 和 A 的房子地址相同。知道房子的地址,我们就不能自己去房子自己改。 A 会写相同的地址,但现在房子会不一样,因为 B 告诉了某人地址,他们更换了房子
  • @CoolCodeBro:您可以更改内容 - 但您无法将其更改为完全不同的房子。 (例如,在您的情况下,Test 不允许您更改 TestString 属性 - 因此无法更改“房屋”的一部分。)
  • @是的,这就是我很好奇的地方。这就是为什么我无法更改字符串。我不想改变油漆或门的尺寸。我有兴趣更换整个房子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 2015-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
相关资源
最近更新 更多