Создается ли класс при вызове статического метода в нестатическом классе? - PullRequest
11 голосов
/ 28 июня 2010

Что именно происходит, когда 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
        }
    }
}

Ответы [ 5 ]

7 голосов
/ 28 июня 2010

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

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

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

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

3 голосов
/ 28 июня 2010

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

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

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

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

1 голос
/ 28 июня 2010

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

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

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

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

0 голосов
/ 28 июня 2010
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 голосов
/ 28 июня 2010

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

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

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

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

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