Rumah >pembangunan bahagian belakang >C++ >Mengapa Menghantar `MyEntityRepository` ke `RepositoryBase` Gagal dalam C#?

Mengapa Menghantar `MyEntityRepository` ke `RepositoryBase` Gagal dalam C#?

DDD
DDDasal
2025-01-06 02:07:41257semak imbas

Why Does Casting `MyEntityRepository` to `RepositoryBase` Fail in C#?

Generik dan Pemutus: Memahami Had Pemutus

Walaupun kejadian ini biasa berlaku, menghantar kelas yang diwarisi kepada kelas asas boleh menjadi rumit, seperti yang ditunjukkan oleh pengecualian masa jalan yang ditemui semasa mencuba perkara berikut kod:

public abstract class EntityBase { }
public class MyEntity : EntityBase { }

public abstract class RepositoryBase<T> where T : EntityBase { }
public class MyEntityRepository : RepositoryBase<MyEntity> { }

MyEntityRepository myEntityRepo = GetMyEntityRepo(); // whatever
RepositoryBase<EntityBase> baseRepo = (RepositoryBase<EntityBase>)myEntityRepo;

Penghantaran ini gagal kerana RepositoryBase sebenarnya bukan kelas asas MyEntityRepository. Oleh itu, menghantar daripada MyEntityRepository ke RepositoryBase adalah tidak sah.

Sebab asas untuk pengehadan ini terletak pada konsep varians generik. Varians generik merujuk kepada keupayaan jenis untuk menukar parameterisasinya dalam cara kovarian atau kontravarian. Walau bagaimanapun, bentuk varians generik ini hanya disokong sebahagiannya dalam C#, terutamanya untuk antara muka dan perwakilan generik.

Dalam konteks yang lebih generik, variasi kovarian membenarkan jenis terbitan menggantikan jenis asasnya dalam senario tertentu . Ini bermakna MyEntityRepository, sejenis yang diperoleh daripada RepositoryBase, boleh menggantikan RepositoryBase dalam kebanyakan keadaan. Walau bagaimanapun, andaian ini tidak sah secara universal disebabkan oleh kemungkinan konflik masa jalan.

Sebagai contoh, pertimbangkan kaedah seperti ini dalam RepositoryBase:

void Add(T entity) { ... }

Menghantar MyEntityRepository ke RepositoryBase akan membuka pintu untuk menambah contoh bukan MyEntity ke repositori, yang tidak diingini. Ini menunjukkan bahawa varians generik kovarian tanpa had boleh menjejaskan integriti seni bina program.

Dalam C# 4, varians generik dibenarkan untuk jenis rujukan dalam antara muka dan perwakilan generik, tetapi bukan untuk kelas. Untuk mendapatkan maklumat yang lebih terperinci, rujuk dokumentasi MSDN Microsoft, siri blog Eric Lippert atau video pembentangan yang diberikan di NDC pada Julai 2010.

Atas ialah kandungan terperinci Mengapa Menghantar `MyEntityRepository` ke `RepositoryBase` Gagal dalam C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn