gpt4 book ai didi

c# - 将对象分配给其他对象会创建副本吗?

转载 作者:太空狗 更新时间:2023-10-30 01:04:46 25 4
gpt4 key购买 nike

我尝试了下面的代码,我得到了 1000 的输出。我听说分配对象必须共享引用而不是复制整个对象内存。这里的结果是不同的。任何人都可以帮忙。

public aaaaa ad = new aaaaa();

static void Main(string[] args)
{
Program p = new Program();
p.fun1();
p.fun2();
}

public void fun1()
{
using(smallclass s = new smallclass())
{
s.j = 1000;
ad.fun1(s);
}
}

public void fun2()
{
ad.fun2();
}
public class aaaaa
{
public smallclass h = new smallclass();
public void fun1(smallclass d)
{
h = d;
}
public void fun2()
{
Console.WriteLine(h.j);
}
}

public class smallclass:IDisposable
{
public int j = 9;

public void Dispose()
{
GC.SuppressFinalize(this);
}
}

更新: 我期望对象引用异常,因为引用的内存在 p.fun1() 中处理;

最佳答案

这是一个简单的例子,它是如何工作的

using System;

namespace ConsoleApplication1
{
internal class Program
{
private static smallclass objA = new smallclass();
private static smallclass objB = new smallclass();

private static void Main(string[] args)
{
showValues();

objA.value = 1000;

showValues();

objB = objA;

showValues();

objA.value = 1055;

showValues();
}

private static void showValues()
{
Console.WriteLine("objA.value: " + objA.value);
Console.WriteLine("objB.value: " + objB.value);

Console.ReadLine();
}
}

internal class smallclass : IDisposable
{
public int value = 0;

public void Dispose()
{
//Here you can remove eventHandlers
//or do some other stuff before the GC will play with it
}
}
}

如你所见

  1. 首先我们创建 2 个对象 objAobjB
    比我们显示的值更像预期的那样它们都是 0

  2. 之后我们增加 objA 的值到 1000objA 的值a 为 1000,objB 的值为保持在 0

  3. 现在我们分配objAobjB所以 objB 的值也得到了 1000

  4. 如果我们现在更改 objA 的值到 1055objB 的值也变了因为objB不再是一个单独的对象,它现在保持不变引用 objA

编辑

现在我将根据您的示例向您展示如何得到错误

更改您的 aaaaa class到:

public class aaaaa
{
public WeakReference<smallclass> h;
public void fun1(smallclass d)
{
h = new WeakReference<smallclass>(d);
}
public void fun2()
{
smallclass k;
if(h.TryGetTarget(out k))
Console.WriteLine(k.j);
else
Console.WriteLine("ERROR ERRROR ERROR");
}
}

并修改你的static void Main(string[] args)到:

    static void Main(string[] args)
{
Program p = new Program();
p.fun1();
GC.Collect();
p.fun2();

Console.Read();
}

好的,让我们完成更改

我们正在使用 WeakReference<T> (您也可以使用 WeakReference )如果 GC 现在遇到我们的对象,他找不到 StrongReference 所以可以收集它

现在到 GC.Collect() 您需要调用它,因为它迫使 GC 完成他的工作(此时此刻)

记住我之前告诉过你的IDisposable将在他销毁对象(AFAIK)之前从 GC 调用,因此有一个地方可以放置在对象被销毁之前需要完成的所有工作

关于c# - 将对象分配给其他对象会创建副本吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21771942/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com