2009-02-14 2 views
4

Прежде всего, статическое ключевое слово.Статическое ключевое слово, переменные состояния/экземпляра и безопасность потоков

Я прочитал несколько статей и прошлых тем, охватывающих ключевое слово static. Я не нашел много сценариев, перечисленных в том, когда я должен его использовать. Все, что я знаю, это не создание объекта в куче, который говорит мне, что было бы хорошо с точки зрения производительности для объекта, который использовался много.

Есть ли другая причина использовать его?

Кроме того, я прочитал что-то о ключевом слове static и о том, как его нельзя использовать с переменными экземпляра или изменить состояние. Может ли кто-нибудь прояснить это? Кажется, что это случай 2 + 2, но я не могу получить ответ (не хватает нескольких фундаментальных и простых знаний).

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

Я разместил это в VB.NET тоже, потому что я не думаю, что разные языки (C#/VB.NET) будут иметь разные правила.

Благодаря

ответ

4

Статическое ключевое слово означает что-то другое в C, но в C# и Java оно объявляет методы и переменные как класса, нежели объекта.

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

Например String.Format() является статическим методом класса String. Вы вызываете это в своем коде, не создавая экземпляр String. Аналогично, Math.Pi будет переменной класса.

Но что-то вроде метода длины не имеет никакого смысла, если оно не действует на конкретный экземпляр строки, поэтому он должен быть методом экземпляра. Например, x = "hello" .Length();

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

В C ключевое слово static обозначает привязку к области видимости файла. Статическая переменная или функция верхнего уровня не получает свое имя, экспортированное в другой скомпилированный объектный код. Таким образом, два файла могут объявлять статические переменные с тем же именем, а не создавать конфликт. У нас нет этой проблемы в C#, потому что существуют пространства имен, а также частные, защищенные и общедоступные ключевые слова, чтобы обозначать видимость.

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

+0

Вижу. Поэтому, если я хочу манипулировать определенной переменной, используйте переменную as instance. В противном случае статические данные не требуются. – dotnetdev

+0

Нет, статические методы должны использоваться, когда вы либо хотите глобальное состояние, либо не нуждаетесь в состоянии напрямую. статический в свободном от состояния контексте является хорошей вещью вообще, поскольку он делает функцию более стабильной/полезной. – ShuggyCoUk

+0

Что означает «не нужно состояние»? Что именно такое состояние? Кроме того, если я отредактирую строку (строка s = «sjsjs» .Substring()), я мог бы использовать метод экземпляра с параметром или статическим методом с параметром. Какая разница? – dotnetdev

-1

На самом деле статические переменные не в стеке, они хранятся в специальном сегменте памяти, который не является ни стек, ни кучи. Кроме того, независимо от того, будет ли переменная находиться в куче или стеке, не влияет на производительность вообще.

Статические функциональные переменные - это переменные, которые существуют в функции, и если изменения сохраняют свое значение между вызовами. Их можно рассматривать как глобальные значения, которые инициализируются по требованию и могут использоваться только в функции, в которой они объявлены. ИМО действительно нет веских оснований использовать статические переменные в функции, отличные от случайных бит тестирования.

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

+0

Я на самом деле имел в виду специальный раздел на куче (высокочастотная куча в соответствии со статьей). Думаю, мне придется это проверить. Кроме того, вы говорите, сохраняете свое значение и используются только в функции, которую они объявили, - это похоже на постоянное значение/readonly с ограниченным объемом. – dotnetdev

+0

Статические переменные изменяемы и могут быть изменены. Поэтому, если у вас есть функция со статическим значением «count», вы можете увеличивать ее каждый раз –

+0

. Я нашел несколько хороших статей по этой проблеме. Действительно, как статическое поле, например, подобно одному заполнителю данных по всем данным, это было бы хорошо для чего-то вроде версии приложения. Вы не хотите больше, чем один из них. Вы бы установили его как статичный и изменили его, но имеете 1 экземпляр. – dotnetdev

0

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

например. String.Empty (которая является общедоступной переменной static readonly). Использование этого не требует создания нового экземпляра строки.

0

Я использую статические переменные для хранения значений (например, запросов sql), которые считываются из файлов, в функциях, которые будут называться alot (как в цикле). Предотвращает попадание диска при каждом вызове функции и является хорошим использованием «скрытия информации».

-1

Вот довольно распространенный способ использования переменных статических классов:

public class Foo 
{ 
    private static Dictionary<string, Foo> Foos = 
     new Dictionary<string, Foo>(); 

    public static Foo Create(string key) 
    { 
     if (Foos.ContainsKey(key)) return Foos[key]; 
     Foos.Add(key, new Foo(key)); 
    } 

    public string Key { get; set; } 

    private Foo(string key) 
    { 
     Key = key; 
    } 
} 

Скрытие конструктора и коллекция позволяет сам класс брокеру все Foo объекты, созданные с помощью приложения.

+0

API-интерфейс Create не является потокобезопасным, так как он не блокирует общие данные/поле Foos, прежде чем подглядывать и добавлять к нему. Если два или более потока одновременно вызывают Create, могут возникать всевозможные несоответствия. Следовательно, это плохой случай использования для статических полей – bhavinb

1

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

Дать поточно-код здоровенный вопрос, который я не буду вдаваться в здесь, но я скажу одну вещь по теме статической безопасности & резьбы.

Большинство методов обеспечения выполнения кода, предназначенных для нескольких потоков вызовов, связаны с какой-либо блокировкой экземпляра объекта. Вы заметите, что в .NET framework (BCL) все статические члены являются потокобезопасными. Это связано с тем, что нет четкого способа узнать, какой экземпляр объекта должен быть заблокирован, чтобы разделить этот ресурс между всеми мыслимыми абонентами.

Старых принципы используются предложить блокировки на самом типе, а именно:

lock (typeof(SomeType)) 
{ 
    SomeType.SomeStaticMethod(...); 
} 

Этот подход в настоящее время не рекомендуются и нецелесообразно, потому что нет никакого способа контролировать порядок доступов к этим объектам блокировки по всем мыслимому вызов потоков. Блокировка на публичных объектах (включая ICollection.SyncRoot, которая теперь устарела по той же причине) открывает дверь в тупиковые блоки. В вышеприведенном случае экземпляр типа общедоступен и не должен быть заблокирован.

Учитывая, что нет единственного экземпляра, который все клиенты статических методов могут разумно согласиться на использование для доступа к статическим членам, команде BCL от Microsoft пришлось сделать все статические члены типичными. К счастью для них, статические члены мало и далеко друг от друга.

Смежные вопросы