main()
{
   A a = new A();
   a.Change();
   Console.Write(a.num);
}
class A
{
   public int num = 0;
   void Change()
   {
       B.ChangeA(this);
   }
}
class B
{
   static void ChangeA(A a)
   {
      a.num = 10;
      a = null;
      try{
          Console.Write(a.num);
      catch{ Console.Write("空指针"); }
   }
}
运行的结果是:
空指针
10
我想让一个对象自己销毁自己,因为编译器不通过this=null,所以我加了个B类用来改变A对象我想,既然 num=10 了,那说明a的确按引用传过来了,而且后来又报了空指针,说明 a=null 也起作用了,但是为什么退出这个方法之后的Console.Write(a.num)却还能照常运行?

解决方案 »

  1.   

    当然是正确的,B.ChangeA(this);这个方法是将class A作为一个参数副本传进去的,也就是说,class B中操作的,是从class A中实例的一个新的class A对象,你在B操作中a = null;只能说明A的副本参数对象被销毁了,而对主函数而言,A本身不会被销毁,如果你想实现你要的功能,就必须回传A参数B.ChangeA(ref this);
      

  2.   

    垃圾收集器是按一定的间隔时间来销毁 == null 的对象的。
      

  3.   


    如果是副本,最后打印的num就应该是0,而不是10
      

  4.   

    我在打印a.num之后还看了a这个对象的内存地址,和最初实例化它时是一样的,按理说,a=null之后a对象的地址应该是0x000000之类的吧,还有,对象a和参数a的内存地址一样,不要怀疑参数a是一个副本
      

  5.   

    不要玩什么“指针”概念。谁告诉你c#的传参“等于c++之类的指针操作”?   B.ChangeA(this);就是给变量a设置了一个(对象)值,之后你给这个变量a又设置了null值,根本没有影响到a的作用域之外!动不动把c#变量看作指针,是一种在个别喜欢借c++概念说事的人的陋习。应该认真学习什么叫做变量,仅此而已。.net不玩指针那种玩意(除非需要为了c++而作一点接口工作时才需要)。
      

  6.   

    .net的传参,就是简单的变量是否赋值的问题。当在参数声明中写ref的时候,会把参数赋值回调用的变量。不写ref,就不会把过程内的参数变量重新赋值给调用时的变量。就算是ref传参的情况,例如        public static void Main()
            {
                var a = new MM { xx = "aa" };
                var c = a;
                Test(ref c);
                var b = a;
            }        private static void Test(ref MM a)
            {
                a = null;
            }这个时候你会发现在Main中调用完Test之后,c已经是null了,但是a仍然指向对象。实际上就算给变量设置null值,也不过是改变了变量值(使得变量不再指向对象),哪里“销毁”了对象了?对象仍然好端端地在内存中,只有GC来收集垃圾的时候才会去销毁它。要使用“指针”来理解变量,画蛇添足编程出错不说,还故弄玄虚。
      

  7.   

    如果你一定要用“指针”这个词,就这样理解:c、c++中的指针是个“裸体”的原生静态内存地址概念,而.net的指针是个包装了的动态对象,根本不是一个档次的概念。
    .net(实际上是10年前的java)利用了一些c++的变量机制的概念是为了让旧的程序员容易理解新的java语言。10年之后把指针概念重新理解,则很累。所以现在干脆把.net的变量跟c++指针划清界限最有效。
      

  8.   

    这个,前辈,能不能再解释下这句?.net的传参,就是简单的变量是否赋值的问题。当在参数声明中写ref的时候,会把参数赋值回调用的变量。 不写ref,就不会把过程内的参数变量重新赋值给调用时的变量。