Статические классы и члены статических классов (руководство по программированию в C#)
Обновлен: Июль 2008
Статический класс в основном такой же, что и нестатический класс, но имеется одно отличие: нельзя создавать экземпляры статического класса. Другими словами, нельзя использовать ключевое слово new для создания переменной типа класса. Поскольку нет переменной экземпляра, доступ к членам статического класса осуществляется с использованием самого имени класса. Например, если имеется статический класс, называемый UtilityClass, имеющий открытый метод, называемый MethodA, вызов метода выполняется, как показано в следующем примере.
UtilityClass.MethodA();
Как и в случае с типами всех классов сведения о типе для статического класса загружаются средой CLR .NET Framework, когда загружается программа, которая ссылается на класс. Программа не может точно указать, когда загружается класс. Но гарантируется загрузка этого класса, инициализация его полей и вызов статического конструктора перед первым обращением к классу в программе. Статический конструктор вызывается только один раз, и статический класс остается в памяти на время существования домена приложения, в котором находится программа.
Статический класс может использоваться как обычный контейнер для наборов методов, работающих на входных параметрах, и не должен возвращать или устанавливать каких-либо внутренних полей экземпляра. Например, в библиотеке классов платформы .NET Framework статический класс System.Math содержит несколько методов, выполняющих математические операции, без требования сохранять или извлекать данные, уникальные для уникального экземпляра класса Math.
Примечание. |
---|
Создание нестатического класса, который допускает создание только одного экземпляра самого себя, см. в документе Реализация Singleton в C#. |
Следующий список предоставляет основные характеристики статического класса:
Содержит только статические члены.
Создавать его экземпляры нельзя.
Он закрыт.
Не может содержать конструкторов экземпляров.
По сути, создания статического класса аналогично созданию класса, содержащего только статические члены и закрытый конструктор. Закрытый конструктор не допускает создания экземпляров класса. Преимущество применения статических классов заключается в том, что компилятор может проверить отсутствие случайно добавленных членов экземпляров. Таким образом, компилятор гарантирует невозможность создания экземпляров таких классов.
Статические классы запечатаны, поэтому их нельзя наследовать. Они не могут быть унаследованы ни от каких классов, кроме Object. Статические классы не могут содержать конструктор экземпляров, но могут содержать статический конструктор. Нестатические классы также должен определять статический конструктор, если класс содержит статические члены, для которых нужна нетривиальная инициализация. Дополнительные сведения см. в разделе Статические конструкторы (руководство по программированию в C#).
Пример
Ниже приведен пример статического класса, содержащего два метода, преобразующих температуру по Цельсию в температуру по Фаренгейту и наоборот.
public static class TemperatureConverter
{
public static double CelsiusToFahrenheit(string temperatureCelsius)
{
// Convert argument to double for calculations.
double celsius = Double.Parse(temperatureCelsius);
// Convert Celsius to Fahrenheit.
double fahrenheit = (celsius * 9 / 5) + 32;
return fahrenheit;
}
public static double FahrenheitToCelsius(string temperatureFahrenheit)
{
// Convert argument to double for calculations.
double fahrenheit = Double.Parse(temperatureFahrenheit);
// Convert Fahrenheit to Celsius.
double celsius = (fahrenheit - 32) * 5 / 9;
return celsius;
}
}
class TestTemperatureConverter
{
static void Main()
{
Console.WriteLine("Please select the convertor direction");
Console.WriteLine("1. From Celsius to Fahrenheit.");
Console.WriteLine("2. From Fahrenheit to Celsius.");
Console.Write(":");
string selection = Console.ReadLine();
double F, C = 0;
switch (selection)
{
case "1":
Console.Write("Please enter the Celsius temperature: ");
F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine());
Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
break;
case "2":
Console.Write("Please enter the Fahrenheit temperature: ");
C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine());
Console.WriteLine("Temperature in Celsius: {0:F2}", C);
break;
default:
Console.WriteLine("Please select a convertor.");
break;
}
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Example Output:
Please select the convertor direction
1. From Celsius to Fahrenheit.
2. From Fahrenheit to Celsius.
:2
Please enter the Fahrenheit temperature: 20
Temperature in Celsius: -6.67
Press any key to exit.
*/
Статические члены
Нестатический класс может содержать статические методы, поля, свойства или события. Статический член вызывается для класса даже в том случае, если не создано экземпляра класса. Доступ к статическому члены всегда выполняется по имени класса, а не экземпляра. Существует только одна копия статического члена, независимо от того, сколько создано экземпляров класса. Статические методы и свойства не могут обращаться к нестатическим полям и событиям в их содержащем типе, и они не могут обращаться к переменной экземпляра объекта, если он не передается явно в параметре метода.
Более привычно объявление нестатического класса с несколькими статическими членами, чем объявлять весь класс как статический. Статические поля обычно используются для следующих двух целей: хранение счетчика числа созданных объектов, или хранение значения, которое должно совместно использоваться всеми экземплярами.
Статические методы могут быть перегружены, но не переопределены, поскольку они относятся к классу, а не к экземпляру класса.
Хотя поле, не может быть объявлено как static const, поле const по своему поведению является статическим. Оно относится к типу, а не к экземплярам типа. Поэтому к полям const можно обращаться с использованием той же нотации ClassName.MemberName, что и используемой для статических полей. Необходим экземпляр объекта.
C# не поддерживает статических локальных переменных (переменных, которые объявлены в области действия метода).
Для объявления статических методов класса используется ключевое слово static перед возвращаемым типом члена, как показано в следующем примере:
public class Automobile
{
public static int NumberOfWheels = 4;
public static int SizeOfGasTank
{
get
{
return 15;
}
}
public static void Drive() { }
public static event EventType RunOutOfGas;
// Other non-static fields and properties...
}
Статические члены инициализируются перед первым доступом к статическому члену и перед вызовом статического конструктора, если он имеется. Для доступа к члену статического класса следует использовать имя класса, а не имя переменной, указывая расположение члена, как показано в следующем примере:
Automobile.Drive();
int i = Automobile.NumberOfWheels;
Если класс содержит статические поля, должен быть предоставлен статический конструктор, который инициализирует эти поля при загрузке класса.
Вызов статического метода генерирует инструкцию вызова в промежуточном языке Microsoft (MSIL), в то время как вызов метода экземпляра генерирует инструкцию callvirt, которая также проверяет наличие ссылок на пустые объекты. Однако чаще всего разница в производительности двух видов вызовов несущественна.
Спецификация языка C#
Дополнительные сведения см. в следующем разделе документа Спецификация языка C#:
- 10.1.1.3 Статические классы
См. также
Основные понятия
Руководство по программированию в C#
Ссылки
Классы (руководство по программированию на C#)
Статические конструкторы (руководство по программированию в C#)
Конструкторы экземпляров (руководство по программированию в C#)
Журнал изменений
Дата |
Журнал изменений |
Причина |
---|---|---|
Июль 2008 |
Добавлены содержимое и примеры кода. |
Улучшение информации. |