Класс инстанцируют, когда статический метод называют в нестатическом классе?

Точно, что происходит когда Foo. SomeCheck () называют в классе Панели? Экземпляр 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
        }
    }
}
12
задан Ian R. O'Brien 28 June 2010 в 17:57
поделиться

5 ответов

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

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

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

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

7
ответ дан 2 December 2019 в 22:04
поделиться

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

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

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

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

3
ответ дан 2 December 2019 в 22:04
поделиться

Это зависит от реализации SomeMethod . Этот метод нужно будет вызывать откуда-то, предположительно из класса «драйвера», который будет создавать экземпляр Bar и вызывать SomeMethod . Например:

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

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

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

public class Driver
{
    public static void Main()
    {
        Bar.SomeMethod();
    }
}
0
ответ дан 2 December 2019 в 22:04
поделиться

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

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

  1. Статические и нестатические методы;
  2. Статические классы и статические члены класса (Руководство по программированию на C#).

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

1
ответ дан 2 December 2019 в 22:04
поделиться
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.

0
ответ дан 2 December 2019 в 22:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: