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

У меня есть статический контейнерный класс, который держит ручку к некоторому классу :

public static class Container
{
    private static A _a;        
    public static void Register(A a) { _a = a; }
    public static void Run() { _a.DoIt(); }
}

Регистрация контейнера случай выполняется в конструктор:

public class A
{
    public A() { Container.Register(this); }        
    public void DoIt() { Console.WriteLine("Running!"); }
}

Теперь, скажем, то, что я регистрирую мой случай, называя метод, который только содержит экземпляр:

public void Init() { var a = new A(); }

Теоретически, компиляция могла быть оптимизирована, чтобы проигнорировать это назначение, или я могу быть на 100% уверен, что является всегда иллюстрировавший примерами, когда я называю Init метод?

Example When I run the following code:

Init();
...
Container.Run();

<закодирует> Контейнер. _ всегда быть определенным и продукция от DoIt метод, написанный пульту?

3
nl ja de

1 ответы

Компилятор в целом не знает, есть ли у конструктора A заметные побочные эффекты, таким образом, это будет всегда называть его. Это может не держать переменную вокруг все же.

Так, конструктора вызовут, но результат не может быть назначен на переменную; вместо этого объект может просто быть немедленно зарегистрирован для сборки мусора, если ничто иное не ссылается на него. (В вашем случае что-то еще ДЕЙСТВИТЕЛЬНО ссылается на него - а именно, Контейнерный класс - таким образом, это не будет собрано из мусора!)

В вашем случае у конструктора явно есть побочные эффекты в любом случае (таким образом, это была бы главная ошибка для компилятора, чтобы оптимизировать далеко требование конструктора).

Таким образом:

  • конструктор будут всегда называть.
  • назначение результата к локальной переменной не может быть сделано, потому что компилятор знает, что у этого нет заметных побочных эффектов.
  • В вашем коде, что-то еще сохраняет ссылку на построенный объект, таким образом, это не будет GCed.
7
добавлено
Очень хороший, большое спасибо за разъяснение!
добавлено автор Anders Gustafsson, источник
Да положительная сторона, I' ve обновил мой ответ, чтобы явно упомянуть это!
добавлено автор Matthew Watson, источник
это не должно держать переменную ' a' который не является проблемой здесь, так как на новый объект сошлется Контейнерный класс, таким образом, она won' t получают GC' d до некоторого другого ' A' регистры с Контейнером
добавлено автор Bond, источник
Microsoft Stack Jobs
Microsoft Stack Jobs
1 788 участник(ов)

Work & freelance only Microsoft Stack. Feed https://t.me/Microsoftstackjobsfeed Чат про F#: @Fsharp_chat Чат про C#: @CSharpChat Чат про Xamarin: @xamarin_russia Чат общения:@dotnettalks

Microsoft Developer Community Chat
Microsoft Developer Community Chat
584 участник(ов)

Чат для разработчиков и системных администраторов Microsoft Developer Community. __________ Новостной канал: @msdevru __________ Баним за: оскорбления, мат, рекламу, флуд, флейм, спам, NSFW контент, а также большое количество оффтоп тем. @banofbot