C# - Преобразование типов 

Page / - Изменено Alexandr Fokin в 2023/06/26 11:34 

Преобразование типов 
Изменено Alexandr Fokin
в 2023/06/26 11:34

Оглавление

AS	Выполняет попытку приведения к родительскому или дочернему типу (относительно типа переменной) интерфейсному типу.
В случае неудачи возвращает null, не выбрасывает ошибку	ParentType p1 = ChildVar as ParentType;
InterfaceType p2 = instanceVar as InterfaceType;
p1 as ChildType	
IS	Проверяет является ли сущность определенным типом.
true/false.	bool p1 = childVar is ParentType;
bool p2 = instanceVar is InterfaceType;

if (instanceVar is InterfaceType interfaceTypeVar)
{
  interfaceTypeVar.InterfaceMethod();
}	
Upcasting and Dowcasting	Также как и AS выполняет попытку приведения к типу, но в случае неудачи бросает Exception.	​ParentType p1 = (ParentType)childVar;
InterfaceType p2 = (InterfaceType)instanceVar;​
(​ChildType)p1;	
implicit and explicit operator	Механизм который при вызове может выглядеть словно (Upcasting and Dowcasting), но на самом деле выполняющий преобразование одного типа в другой (подразумевает логику создания экземпляра целевого типа и наполнение его данными на основе переданной сущности).
В теле класса может быть определен метод как преобразование экземпляров класса в экземпляры внешнего типа, так и экземпляр внешнего типа в экземпляр класса.

Имеет определенные ограничения: например не позволяет указывать преобразования дочернего типа к родительскому иначе бы приводил к неоднозначности.
Во многих случаях лучше явно реализовать модуль преобразования в виде отдельного компонента бизнес логики (Converter / Transformator / Mapper), а не использовать данный механизм. Механизм больше подходит для преобразования базовых или примитивных типов (Например наличие в проекте собственного специализированного числового типа данных, которые преобразуется в некоторые стандартные типы).	class MyClass1
{
 public static implicit operator Type1 (MyClass1 instance)
  { /*...*/ }  
}
class MyClass2
{
 public static explicit operator Type1 (MyClass2 instance)
  { /*...*/ }
}

static void Action(Type1 param){ /*...*/ }

MyClass1 myClass1Var;
MyClass2 myClass2Var;

Action(myClass1Var); //implicit
Action((Type1)myClass1Var); //explicit	
Ограничения для Generic типов	 	interface Logic1
{
 //В случае struct приведет к упаковке
 void Method1(ParameterInterfaceType param)
}

interface Logic2
{
 //В случае struct не будет упаковки, 
 //произойдет обычная передача параметра с копированием
 void Method1<T>(T param) 
   where T : ParameterInterfaceType 
}	
Ковариантность и контравариантность	Ковариантность и контравариантность обобщенных интерфейсов
https://metanit.com/sharp/tutorial/3.27.php