Je suis passé en C # 8 sur l'un de mes projets. Et j'ai déplacé toutes mes switch
déclarations vers des expressions. Cependant, j'ai découvert que mon projet a commencé à fonctionner différemment et j'ai découvert que c'était à cause de l' switch
expression. Permet d'obtenir ce code par exemple
class Program
{
public enum DataType
{
Single,
Double,
UInt16,
UInt32,
UInt64,
Int16,
Int32,
Int64,
Byte
}
static void Main(string[] args)
{
dynamic value1 = 5;
dynamic value2 = 6;
var casted = CastToType(value1, DataType.Int16);
var casted1 = CastToTypeExpression(value2, DataType.Int16);
var type = casted.GetType(); // Int16
var type1 = casted1.GetType(); // Double
var bytes = BitConverter.GetBytes(casted); // byte arr with 2 el => [5, 0] <- expected behavior
var bytes1 = BitConverter.GetBytes(casted1); // byte arr with 8 el => [0, 0, 0, 0, 0, 0, 24, 64]
}
public static dynamic CastToType(dynamic value, DataType type)
{
switch (type)
{
case DataType.Byte:
return (byte)value;
case DataType.Double:
return (double)value;
case DataType.Int16:
return (short)value;
case DataType.Int32:
return (int)value;
case DataType.Int64:
return (long)value;
case DataType.Single:
return (float)value;
case DataType.UInt16:
return (ushort)value;
case DataType.UInt32:
return (uint)value;
case DataType.UInt64:
return (ulong)value;
default: throw new InvalidCastException();
}
}
public static dynamic CastToTypeExpression(dynamic value, DataType type)
{
return type switch
{
DataType.Byte => (byte)value,
DataType.Double => (double)value,
DataType.Int16 => (short)value,
DataType.Int32 => (int)value,
DataType.Int64 => (long)value,
DataType.Single => (float)value,
DataType.UInt16 => (ushort)value,
DataType.UInt32 => (uint)value,
DataType.UInt64 => (ulong)value,
_ => throw new InvalidCastException(),
};
}
}
J'ai écrit le résultat sous forme de commentaire, mais tl; dr lorsque le commutateur classique est utilisé, la conversion de la valeur renvoie la valeur dans le type attendu, mais lorsque l'expression de commutateur est utilisée, elle renvoie le type "Double", résultant en différents byte[]
lors de l'obtention du octets de la valeur.
Quelle est la différence entre les deux? Qu'est-ce que je manque?
Réponses:
Dans votre formulaire de déclaration de commutateur , chaque branche renvoie directement une valeur. C'est la conversion directe du type numérique en
object
, car c'est effectivement le type de retour de la méthode.Votre forme d' expression de commutateur est légèrement différente. Il extrait d'abord un résultat de l'expression de commutateur, puis convertit ce résultat en type de retour déclaré. Alors, quel est le type de l'expression switch? C'est le "meilleur" type parmi tous les types d'expressions individuelles dans les bras de l'expression switch.
Tous ces types peuvent être implicitement convertis en
double
(qui est l'un des types lui-même), c'est donc le meilleur type. Votre méthode d'expression de commutateur est donc équivalente à:Vous pouvez voir ce "meilleur type" sans utiliser d'expression de commutateur, en utilisant des tableaux typés implicitement:
Ici, le type de
array
est supposé êtredouble[]
.la source