BasicKnowledgeCSharp/LessonsAndTasks/Lesson 81 - Структуры и классы - отличия, struct vs class/Program.cs
Dvurechensky 058c8f2679 1.0
Main
2024-10-05 09:59:53 +03:00

104 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
/*
* структуры
*/
/*
* !!! КОГДА использовать структуру а когда нет !!!!
* Если в структуре нужно представить тип данных состоящий из примитивных типов
* которые логически просто должны быть вместе (мало полей)(пример структура Vector из UNITY)
* (только в том случае если не нужно использовать полиморфизм
* и наследование для этого типа данных) - выйгрыш в производительности
* невелируем сборщик мусора
*/
/// <summary>
/// Структуры - это тоже самое что и класс, только
/// они являются значимым (а не ссылочным) типом и не имеют наследования (но ИНТЕРФЕЙСЫ имеют)
/// Классы - ссылочный тип (reference type - управляемая куча)
/// у классов есть Finalizer(как Деструктор)
/// </summary>
public class ClassPoint
{
public ClassPoint() { }
public int X { get; set; }
public int Y { get; set; }
public virtual void Print()
=> Console.WriteLine($"X: {X}, Y {Y}");
/// <summary>
/// Мы можем переопределить его работу в классе
/// </summary>
~ClassPoint() { }
}
interface IInterface
{
void Print();
}
/// <summary>
/// Значимый тип (value types - стек, ссылки на значения - в куче) - но также может храниться в управляемой куче
/// не работают virtual override при наследовании, protected для свойств и методов
/// мы не можем переопределить работу Finalizer (аналог деструктора в классах)
/// не можем инициализировать поля или свойства напрямую, задать переменные
/// реализация ctor конструктора без параметров невозможна
/// </summary>
public struct StructPoint : IInterface
{
public int X { get; set; }
public int Y { get; set; }
public StructPoint(int x, int y)
{
X = x;
Y = y;
}
public void Print() => Console.WriteLine($"X: {X}, Y {Y}");
}
class Program
{
static void Foo(ClassPoint classPoint)
{
classPoint.X++;
classPoint.Y++;
}
static void Bar(StructPoint structPoint)
{
structPoint.X++;
structPoint.Y++;
}
static void Main()
{
// при инициализации нужно найти место в управляемой куче,
// разместить там данные и получить на них ссылку - отсюда скорость работы выше
// плюс для очистки мусора замедляется работа всей программы
// инициализируем экземпляр класса в управляемую кучу
var classPoint = new ClassPoint() { X = 2, Y = 3 };
// практически нулевая скорость создания объекта структуры (там уже данные)
// инициализируем поля структуры (помещает туда дефолтные значения)
var structPoint = new StructPoint() { X = 3, Y = 2 };
Foo(classPoint); // тут передается ссылка (значения изменятся в экземпляре класса)
Bar(structPoint); // структуры передаются по значению (значения не изменятся в экземпляре структуры - без ref)
IInterface myInterface = structPoint;
classPoint.Print();
myInterface.Print();
// каким образом работает метод Equals при сравнении структур и классов
var classPoint1 = new ClassPoint() { X = 2, Y = 3 };
var classPoint2 = new ClassPoint() { X = 2, Y = 3 };
bool classesAreEqual = classPoint1.Equals(classPoint2); // false - по умолчанию сравнивает не значения, а ссылки
Console.WriteLine($"Equals class: {classesAreEqual}");
var structPoint1 = new StructPoint() { X = 2, Y = 3 };
var structPoint2 = new StructPoint() { X = 2, Y = 3 };
bool structesAreEqual = structPoint1.Equals(structPoint2); // true - по умолчанию сравнивает значения, а не ссылки
Console.WriteLine($"Equals struct: {structesAreEqual}");
Console.ReadKey();
}
}