2017-02-15 14 views
3

Может кто-то пожалуйста, подробно мне подробно следующий сценарий, было бы удобнее, если объяснение включает в себя выделение памяти и его ссылку для трех случаев:Почему поток выполнения следующих случаев был другим?

  1. Как поток выполняется в трех случаях?
  2. Почему поток отличается в трех случаях?
  3. Хотя существует круговая зависимость между двумя классами, почему один случай 1 выполняется, когда оставшиеся случаи были провалены?

случае, если один

namespace CircularDependency_1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new A(); 
      Console.WriteLine("executed"); 
      Console.ReadLine(); 
     } 
    } 

    public class B 
    { 
     public static A a = new A(); 

     public B() 
     { 

      Console.WriteLine("Creating B"); 
     } 
    } 

    public class A 
    { 
     public static B b = new B(); 

     public A() 
     {   
      Console.WriteLine("Creating A"); 
     } 
    } 
} 

ВЫХОД

Creating A 
Creating B 
Creating A 
executed 

случае два

namespace CircularDependency_1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new A(); 
      Console.WriteLine("executed"); 
      Console.ReadLine(); 
     } 
    } 

    public class B 
    { 
     public static A a; 

     public B() 
     { 
      a = new A(); 
      Console.WriteLine("Creating B"); 
     } 
    } 

    public class A 
    { 
     public static B b; 

     public A() 
     {  
      b = new B(); 
      Console.WriteLine("Creating A"); 
     } 
    } 
} 

OUTPUT Процесс прекращается из-за ошибки StackOverflowException.

ПРИМЕР ТРИ

namespace CircularDependency_1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      A a = new A(); 
      Console.WriteLine("executed"); 
      Console.ReadLine(); 
     } 
    } 

    public class B 
    { 
     public A a; 

     public B() 
     { 
      a = new A(); 
      Console.WriteLine("Creating B"); 
     } 
    } 

    public class A 
    { 
     public B b; 

     public A() 
     {  
      b = new B(); 
      Console.WriteLine("Creating A"); 
     } 
    } 
} 

ВЫХОД Процесс завершен из-за StackOverflowException.

+0

Почему вы добавили ярлык 'java'? – SomeDude

+0

@svasa Я думаю, что вопрос скорее связан с OOPS, а не с языком. –

+1

Я голосую, чтобы закрыть этот вопрос как не относящийся к теме, потому что [Вопросы, требующие помощи в домашней работе, должны содержать резюме работы, которую вы сделали до сих пор, чтобы решить проблема и описание трудности, с которой вы ее решаете] (http://stackoverflow.com/help/on-topic). – RealSkeptic

ответ

2

@ Непостоянный, вы близки, но не правы. Причина, по которой выполняется первый случай и два других случая, не только потому, что объекты создаются внутри конструктора или внутри класса (вне конструктора).Чтобы это доказать, попробуйте сделать поля a и b не статичными в классах B и A (случай один) соответственно; и вы увидите, что он потерпит неудачу, хотя объекты создаются вне конструктора.

Случай 2 и 3 не работает по причинам, объясняемым @Versatile. Случай 1 выполняется из-за static членов. Рассмотрим поток:

В Main методе линия A a = new A() начинается создание a объекта. В этом процессе объект класса B будет создан из-за строки public static B b = new B() - эта сама строка начнет создавать другой объект класса A из-за строки public static A a = new A() в теле класса B. Теперь придет волшебство (которое не срабатывает круговой зависимостью). Эта строка, public static A a = new A(), начнет создавать другой объект класса A, создав этот объект, он не создаст другого объекта класса B, потому что он является статическим членом A, и он уже был создан. Как известно, статические члены класса разделяются между всеми экземплярами класса. Поэтому он не инициирует создание другого объекта класса B. В итоге мы получаем три экземпляра классов в порядке: A, B, A.

UPDATE

Интересно заметить, что в первом случае, что произойдет, если мы инициализировать статический элемент внутри конструктора. Несмотря на то, что классы A и B объявляют статические члены, выполнение не будет выполнено из-за циклической зависимости. Это связано с тем, что статические элементы не инициализируются до выполнения конструктора.

+0

спасибо, что указал. Я предположил, что использование статики было очевидно, что объект будет создан только один раз и более того, поскольку ему назначается новая память на этой линии, следовательно, он не переходит в рекурсивный вызов. – Versatile

1

1. Как проходит поток в трех случаях? Сначала вызывается статическая пустота Main(), а затем вызывается конструктор объекта A из-за строки кода A a = new A();

2. Почему поток отличается в трех случаях?

3. Хотя существует круговая зависимость между двумя классами, почему случай 1 выполняется только в том случае, когда остальные случаи были провалены?

Оба вышеуказанных сценария соблюдаются по той же причине. Если вы внимательно присмотритесь, вы назначаете память следующим образом. Case1 в классе, а не в конструкторе. т.е.

public class A 
{ 
    public static B b = new B(); 
} 

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

Дело 2 и случай 3: Память к объектам A и B назначается в конструкторе, то есть в конструкторе A память назначается B, а в конструкторе памяти B назначается A, что приводит к вызову соответствующего класса конструкторы снова и снова, пока не будет выбрано исключение.