C# Language
Структуры
Поиск…
замечания
В отличие от классов, struct
является типом значения и создается по умолчанию в локальном стеке, а не в управляемой куче. Это означает, что после того, как конкретный стек выходит за пределы области, struct
де-распределяется. Содержащиеся ссылочные типы де-выделенной struct
s также перемещаются, как только GC определяет, что они больше не ссылаются на struct
.
struct
s не может наследовать и не может быть основанием для наследования, они неявно запечатаны и также не могут включать protected
члены. Однако struct
может реализовать интерфейс, как это делают классы.
Объявление структуры
public struct Vector
{
public int X;
public int Y;
public int Z;
}
public struct Point
{
public decimal x, y;
public Point(decimal pointX, decimal pointY)
{
x = pointX;
y = pointY;
}
}
Поля
struct
экземпляра могут быть заданы с помощью параметризованного конструктора или индивидуально после построенияstruct
.Конкретные члены могут быть инициализированы только конструктором.
struct
определяет закрытый тип, который неявно наследуется от System.ValueType.Структуры не могут наследовать ни от какого другого типа, но могут реализовывать интерфейсы.
Структуры копируются при присваивании, то есть все данные копируются в новый экземпляр, а изменения в один из них не отражаются другим.
Строка не может быть
null
, хотя она может использоваться как тип сnull
значением:Vector v1 = null; //illegal Vector? v2 = null; //OK Nullable<Vector> v3 = null // OK
Структуры могут быть созданы с использованием или без использования
new
оператора.//Both of these are acceptable Vector v1 = new Vector(); v1.X = 1; v1.Y = 2; v1.Z = 3; Vector v2; v2.X = 1; v2.Y = 2; v2.Z = 3;
Тем не менее,
new
оператор должен использоваться для использования инициализатора:Vector v1 = new MyStruct { X=1, Y=2, Z=3 }; // OK Vector v2 { X=1, Y=2, Z=3 }; // illegal
Структура может объявлять все, что может объявить класс, за несколькими исключениями:
- Структура не может объявить конструктор без параметров. Поля
struct
экземпляра могут быть заданы с помощью параметризованного конструктора или индивидуально после построенияstruct
. Конкретные члены могут быть инициализированы только конструктором. - Структура не может объявлять элементы защищенными, поскольку она неявно закрыта.
- Поля Struct могут быть инициализированы только в том случае, если они являются константными или статическими.
Использование структуры
С конструктором:
Vector v1 = new Vector();
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Vector v1 = new Vector();
//v1.X is not assigned
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=0,Y=2,Z=3
Point point1 = new Point();
point1.x = 0.5;
point1.y = 0.6;
Point point2 = new Point(0.5, 0.6);
Без конструктора:
Vector v1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
//Output ERROR "Use of possibly unassigned field 'X'
Vector v1;
v1.X = 1;
v1.Y = 2;
v1.Z = 3;
Console.WriteLine("X = {0}, Y = {1}, Z = {2}",v1.X,v1.Y,v1.Z);
// Output X=1,Y=2,Z=3
Point point3;
point3.x = 0.5;
point3.y = 0.6;
Если мы используем конструкцию с ее конструктором, у нас не будет проблем с неназначенным полем (каждое неназначенное поле имеет нулевое значение).
В отличие от классов, структура не должна быть построена, то есть нет необходимости использовать новое ключевое слово, если только вам не нужно называть один из конструкторов. Структуре не требуется новое ключевое слово, потому что это тип значения и, следовательно, не может быть нулевым.
Интерфейс реализации проекта
public interface IShape
{
decimal Area();
}
public struct Rectangle : IShape
{
public decimal Length { get; set; }
public decimal Width { get; set; }
public decimal Area()
{
return Length * Width;
}
}
Структуры копируются при назначении
Sinse structs - типы значений, все данные копируются при назначении, а любая модификация новой копии не изменяет данные для оригинальной копии. В приведенном ниже фрагменте кода показано, что p1
копируется на p2
а изменения, сделанные на p1
, не влияют на экземпляр p2
.
var p1 = new Point {
x = 1,
y = 2
};
Console.WriteLine($"{p1.x} {p1.y}"); // 1 2
var p2 = p1;
Console.WriteLine($"{p2.x} {p2.y}"); // Same output: 1 2
p1.x = 3;
Console.WriteLine($"{p1.x} {p1.y}"); // 3 2
Console.WriteLine($"{p2.x} {p2.y}"); // p2 remain the same: 1 2