Terangkan misteri Enumerable.Cast()
dilemparkanInvalidCastException
Dalam .NET 3.5 SP1, pengecualian Cast<T>()
dilemparkan secara mengelirukan apabila menukar IEnumerable
menggunakan InvalidCastException
. Pertimbangkan kod berikut:
<code class="language-csharp">IEnumerable<int> list = new List<int>() { 1 }; IEnumerable<long> castedList = list.Cast<long>(); Console.WriteLine(castedList.First());</code>
Mengapa kod ini membuang pengecualian?
Tingkah laku luar biasa ini berpunca daripada perubahan dalam tingkah laku kaedah Cast<T>()
antara .NET 3.5 dan .NET 3.5 SP1. Sebelum SP1, Cast<T>()
bertindak ke atas IEnumerable<T>
, membenarkan penukaran langsung. Walau bagaimanapun, dalam SP1, ia telah diubah suai untuk berfungsi pada IEnumerable
, yang bermaksud elemen dinyahkotak ke System.Object
sebelum ditukar.
Operasi nyahkotak ini menghasilkan InvalidCastException
kerana tidak seperti menukar int
terus kepada long
, menukar int
berkotak kepada long
tidak dibenarkan. Secara berkesan, kod ini cuba melakukan perkara berikut:
<code class="language-csharp">int i = 1; object o = i; long l = (long)o;</code>
Ini juga akan menghasilkan InvalidCastException
yang sama.
Penyelesaian dan penjelasan
Untuk menyelesaikan masalah ini, anda boleh menggunakan ungkapan lambda untuk menukar elemen secara eksplisit:
<code class="language-csharp">var castedList = list.Select(i => (long)i);</code>
Ini akan berjaya menukar elemen kepada long
.
ini ialah Cast<T>()
ialah kaedah lanjutan daripada IEnumerable
, bukan daripada IEnumerable<T>
. Apabila elemen mencapai tahap transformasi, ia telah pun dikotak-kotak sebagai object
. Ini menghasilkan object
apabila menukar daripada InvalidCastException
kepada jenis tertentu.
Atas ialah kandungan terperinci Mengapakah `IEnumerable.Cast()` Melemparkan `InvalidCastException` dalam .NET 3.5 SP1?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!