Является ли экземпляр класса, когда статический метод вызывается в нестационарном классе?

Точно, что происходит, когда Foo.SomeCheck() вызывается в классе Bar? Является экземпляром Foo, созданным для вызова SomeCheck()? Если да, то этот экземпляр хранится в куче, и он когда-либо собирался через сбор мусора?

public class Foo() {
    public static bool SomeCheck() {
        return true;
    }
}

public class Bar() {
    public void SomeMethod() {
        // what happens when we access Foo to call SomeCheck?
        if (Foo.SomeCheck()) {
            //do something
        }
    }
}

Ответ 1

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

Теперь ваш пример неверен, но предположительно, строка: if( Foo.SomeCheck() ) вызывает статический метод SomeCheck, используя имя типа: Foo - не экземпляр. Однако Bar должен быть создан для того, чтобы сделать этот вызов - , но в вашем примере у вас нет хорошо сформированного экземпляра Bar. Код, как правило, должен существовать внутри метода (или инициализатора элемента), которого у вас здесь нет.

Чтобы ответить на другие части вашего вопроса. Предполагая, что этот код является частью метода экземпляра, что-то должно создать экземпляр Bar - и вызвать этот метод. Чтобы что-то могло создать или иначе получить экземпляр Bar. Типы ссылок всегда будут свертываться на куче, но здесь это в основном не имеет значения.

Что касается сбора мусора, вы, как правило, не должны беспокоиться об этом. Среда выполнения .NET обеспечивает очистку экземпляров, на которые не ссылаются ни один корневой объект в вашей программе. Корни обычно являются экземплярами, которые находятся где-то в callstack или на которые ссылаются статические члены того или иного типа. Поскольку мы не видим здесь никакого кода, который создает или ссылается на Bar, невозможно сказать, когда он будет собран. Например, если Bar является одноэлементным и хранится где-то в статической переменной, он может жить очень долго - возможно, весь срок службы программы. Вы не можете знать, не видя весь код, который управляет и управляет Bar.

Ответ 2

Я настоятельно рекомендую прочитать следующую статью:

Сверлить внутри .NET Framework Internals, чтобы узнать, как среда CLR создает объекты выполнения

В нем объясняется, как среда выполнения .NET работает на низком уровне и объясняет внутренние нюансы, такие как Loader Heaps и как работают статические классы/члены. С технической точки зрения, существует первоначальная инстанция "статического instnace" статических членов классов. Однако это инициирование обрабатывается средой выполнения иначе, чем обрабатывается для экземпляров класса. Статические классы хранятся на кучи загрузчика, которые не управляются GC. Кучи погрузчика выделяются и выращиваются статическим образом и не уплотняются. Статья является отличным чтением и должна дать вам представление о том, как работает CLR.

(ПРИМЕЧАНИЕ. Я не уверен, насколько достоверна эта статья для .NET. 4. Я знаю, что в .NET 4 были изменения GC, однако я не уверен, сколько фундаментальных изменений времени выполнения существует. DLR и другие функции могут отклоняться от объяснения в приведенной выше статье до некоторой степени.)

Ответ 3

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

Пожалуйста, ознакомьтесь с этими ссылками для получения дополнительной информации:

Я надеюсь, что это поможет! =)

Ответ 4

Это зависит от реализации SomeMethod. Метод должен вызываться где-то, предположительно, "драйвер", который создавал бы бар и вызывал SomeMethod. Например:

public class Driver
{
    public static void Main()
    {
        Bar bar = new Bar();
        bar.SomeMethod();
    }
}

Учитывая текущую реализацию SomeMethod, да, вы должны были бы создать экземпляр.

Однако, пока SomeMethod делает только вызов другого статического метода, мы могли бы сделать его статическим. В этом случае вам не нужно будет создавать экземпляр Bar для вызова метода. то есть.

public class Driver
{
    public static void Main()
    {
        Bar.SomeMethod();
    }
}

Ответ 5

public class Manipulate
    {        
        public static int Main(string[] args) {
            Bar bar = new Bar();
            bar.BarFoo();
            Console.ReadKey();
            return 0;
        }

    }
    public class Foo {
        public static bool SomeCheck() {
            return true;
        }
    }
    public class Bar {
        // what happens when we access Foo to call SomeCheck?
        public void BarFoo() {
            if (Foo.SomeCheck()) {
                Console.WriteLine("Hello am true");
            }
        }
    }

Да, вам нужно создать экземпляр Bar, но не для класса Foo, так как это статический метод. Единственное отличие состоит в том, что статические методы вызывают на уровне класса (время компиляции), а не на уровне объекта (время выполнения), поэтому вам не нужно создавать экземпляр класса Foo.