forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   С# (http://forum.boolean.name/forumdisplay.php?f=128)
-   -   Донный вопрос (http://forum.boolean.name/showthread.php?t=19092)

radiobutton 12.04.2014 16:07

Донный вопрос
 
Представим что у нас есть объект класса A. В одном из его методов передаем какое нить лямбда выражение в объект класса B, в котором сохраняется ссылка на него.
Что будит с лямбда выражением если на класс A потеряется ссылка в графе ссылок и условия для сборки мусора станут удачными. ? :)

PHP код:

Class Program
{
   private 
B _b;
   
void Main(string[] args)
   {
       
A a = new A();
       
_b = new B();
      
a.go(_b);
   }
}

Class 
A
{
     public 
go(B b)
     {
         
b.setAction(()=>{Debug.WriteLine("ololo");});
     }
}

Class 
B
{
    private 
Action _action;
    public 
void setAction(Action action)
    {
        
_action action;
    }



pax 13.04.2014 10:27

Ответ: Донный вопрос
 
В данном примере видимо лямбда выражение не связанно с классом A. И к чему такой вопрос? Поймал какие-то проблемы?

radiobutton 13.04.2014 18:07

Ответ: Донный вопрос
 
Цитата:

Сообщение от pax (Сообщение 278885)
В данном примере видимо лямбда выражение не связанно с классом A. И к чему такой вопрос? Поймал какие-то проблемы?

Нет. просто было интересно всегда, а проверять никак руки не доходили.

а если так?)

PHP код:

class A
    
{
        public 
void go(B b)
        {
            
b.setAction(lambda);
        }

        private 
void lambda(object e)
        {
            
Debug.WriteLine("ololo");
        }
    }

    class 
B
    
{
        public 
delegate void lol(object o);
        
lol _action;
        public 
void setAction(lol action)
        {
            
_action action;
        }
    } 


johnk 14.04.2014 11:27

Ответ: Донный вопрос
 
В первом примере, как сказал pax, копируется сама лямбда - ()=>{Debug.WriteLine("ololo");} - а не "часть" экземпляра класса А.

Во втором ты делаешь замыкание на метод класса, поэтому очевидно, что ссылка на экземпляр есть, сборщик не сможет удалить такой объект.

PHP код:

static void Main()
      {
         var 
= new A();
         var 
= new B();

         
a.go(b);

         for (
int i 010000i++)
         {
            var 
garbage = new byte[1024 1024];
            
GC.Collect();
         }

         
Console.Read();
      }

      class 
A
      
{
         public 
void go(B b)
         {
            
b.setAction(lambda);
         }

         private 
void lambda(object e)
         {
            
Debug.WriteLine("ololo");
         }
      }

      class 
B
      
{
         public 
delegate void lol(object o);
         
lol _action;
         public 
void setAction(lol action)
         {
            
_action action;
         }
      } 

Если поставить точку останова после/на Console.Read(), видно, что оба экземпляра живы.


Часовой пояс GMT +4, время: 14:15.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot