Saya telah beralih ke C # 8 pada salah satu proyek saya. Dan saya telah memindahkan semua switch
pernyataan saya ke ekspresi. Namun saya menemukan bahwa proyek saya mulai bekerja secara berbeda dan saya menemukan bahwa itu karena switch
ekspresi. Mari kita dapatkan kode ini misalnya
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(),
};
}
}
Saya telah menulis hasilnya sebagai komentar, tetapi tl; dr ketika switch klasik digunakan casting nilai mengembalikan nilai dalam Type yang diharapkan, tetapi ketika switch switch digunakan mengembalikan tipe "Double", menghasilkan perbedaan byte[]
ketika mendapatkan byte nilai.
Apa perbedaan keduanya? Apa yang saya lewatkan?
Jawaban:
Di saklar Anda formulir pernyataan , setiap lengan mengembalikan nilai secara langsung. Itu mengkonversi dari tipe numerik langsung ke
object
, karena itu secara efektif jenis pengembalian metode.Saklar Anda Bentuk ekspresi sedikit berbeda. Pertama-tama mengekstrak hasil dari ekspresi sakelar, lalu mengonversi hasil itu ke tipe pengembalian yang dinyatakan. Jadi apa jenis ekspresi saklar? Ini adalah tipe "terbaik" dari semua tipe ekspresi individu di lengan ekspresi switch.
Semua tipe tersebut dapat secara implisit dikonversi
double
(yang merupakan salah satu tipe itu sendiri), jadi itulah tipe terbaik. Jadi metode pengalihan ekspresi Anda sama dengan:Anda dapat melihat "tipe terbaik" ini tanpa menggunakan ekspresi sakelar, menggunakan larik yang diketik secara implisit:
Di sini jenis
array
disimpulkandouble[]
.sumber