C# 将对象指定给其他对象是否会创建副本?
我尝试了下面的代码,得到了1000的输出。我听说分配对象必须共享引用,而不是复制整个对象内存。这里的结果是不同的。有人能帮忙吗C# 将对象指定给其他对象是否会创建副本?,c#,object,reference,garbage-collection,dispose,C#,Object,Reference,Garbage Collection,Dispose,我尝试了下面的代码,得到了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 smallcla
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();
}
更新:
我期望在p.fun1()中释放引用的内存时出现对象引用异常 不,assinging不是一个“新”语句,它复制了。。。。作为引用,它不会创建新对象。一节课
对于结构,它是这样做的
我建议通过阅读文档或一本书来学习C#-这些基本知识通常在这些文档或书中被非常详细地处理。下面是一个简单的例子,说明如何使用assinging
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
}
}
}
就像你看到的
objA
和objB
我们显示的值与预期值相同,它们都是0
objA
的值增加到1000
objA
a的值为1000,objB
的值保持为0objA
和objB
因此,objB
的值也得到了1000objA
的值更改为1055
objB
的值也会更改
因为objB不再是一个单独的对象,所以它现在保持不变
类似于objA的引用aaaaa等级
更改为:
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)
{
Program p = new Program();
p.fun1();
GC.Collect();
p.fun2();
Console.Read();
}
好的,让我们完成这些变化
我们正在使用(您也可以使用)
如果GC现在遇到我们的对象,他无法找到StrongReference,因此可以收集它
现在,您需要调用它,因为它迫使GC执行其工作(此时此刻)
请记住,正如我之前告诉您的,在GC销毁对象(AFAIK)之前,它将从GC中被调用,因此在销毁对象之前,有地方可以放置所有需要执行的操作我已将dispose函数中的GC.SuppressFinalize替换为GC.Collect(),但这并不能释放内存。。结果我收到了1000英镑 我猜,由于它包含其他引用(变量h),即使我们显式调用它,GC也不会释放内存 因此,无论分配的(新)对象是否超出范围,我们都可以很好地传递和分配对象
如果我错了,请纠正我 如果您想到每一个引用类型变量、字段、参数、数组插槽或其他此类存储位置都有“null”或“object#24601”[或其他数字],您就不会犯太大的错误。实际上,只有少数几件事可以通过引用来完成:
myCar
是某个引用类型的变量,则类似myCar.Color=CarColors.Blue的语句根本不会影响变量myCar
。相反,它将观察到myCar
持有[例如]“Object#8675309”,然后要求系统访问Object#8675309的Color
属性或字段。相反,如果otherCar
恰好持有“object#90210”,则形式为otherCar=myCar
的语句不会对object#8675309或object#90210做任何处理,而是将存储在otherCar
中的“90210”替换为“8675309”
只要存在对对象的任何形式的引用,就可以保证对象存在,但是如果有两个对象,虽然相互引用,但不被宇宙中的任何其他对象引用,那么这两个对象可能同时停止存在。这条规则是绝对的,但也有一些曲折:代码可能会向对象请求WeakReference
;只要存在对某个对象的弱引用,就可以保证该对象存在,但如果系统发现不存在对该对象的强引用,它将使对该对象的每个WeakReference
无效。此外,系统保留了一个列表,其中列出了在放弃时希望得到通知的所有对象。如果系统发现此列表包含对某个对象的唯一引用,则会将该对象移动到一个强烈引用的对象列表中,该列表中的Finalize
方法应在第一个方便的时机运行。当对象的Finalize
方法运行时,引用将从后面的列表中删除。如果同时未在任何位置存储对该对象的引用,则该对象将不再存在。您的预期输出是什么?当你不说出你的想法时,很难判断你的想法哪里错了。代码运行良好:预期输出为1000
。问题不太清楚。输出1000是预期值。可能是告诉您期望的输出有助于解释。我期望输出为异常。因为赋值h=d,必须复制对象的引用,而不是对象的内存。考虑到这一点,它只是共享引用,并且由于对象是在p.fun1()中处理的,因此结果如何变成1000是一个问题。您没有处理任何内存。您不明白IDisposable
和Dispose
是如何工作的。当您在垃圾收集器中清理对象时,您的Dispose
方法仅将该对象标记为不调用终结器(这就是它的作用)。它根本不会释放任何内存。@MuthukumarPalaniappan请尝试一本关于C#basics的书。不,没有办法释放对象。你可以强制垃圾收集,但这会产生严重的副作用。看看我的,如果你这样做,你会得到你所期望的好结果
static void Main(string[] args)
{
Program p = new Program();
p.fun1();
GC.Collect();
p.fun2();
Console.Read();
}