C # Tidak dapat mengubah dari kelas ke antarmuka [duplikat]

Dec 14 2020

Saya baru menggunakan antarmuka, tetapi setelah membacanya, saya pikir gagasan antarmuka adalah bahwa kelas yang diturunkan dari antarmuka akan diterima di mana pun antarmuka itu diterima. Ini kode saya:

public interface IPersonOfInterest
{ 
    //code requiring certain info to exist
}    
public abstract class PersonOfInterest
{
    public string[] GetBigPersonsInfo(List<IPersonOfInterest> FromList)
    {
        //code to gather a list of info that is guaranteed to be in any IPersonOfInterest
        return new string[] { };
    }
}

public class BigDonors : PersonOfInterest, IPersonOfInterest
{
    public List<BigDonors> SuchDonors = new List<BigDonors>();
    public void GimmeDemInfos()
    {
        string[] GetInfo = GetBigPersonsInfo(SuchDonors); //<-- compiler error here
    }
}

Seperti yang Anda lihat, BigDonorsberasal dari IPersonOfInterestantarmuka. Jadi mengapa ini memberikan kesalahan kompiler, mengatakan daftar BigDonortidak dapat diubah menjadi daftar IPersonOfInterest? Saya mengerti bahwa mereka bukanlah hal yang sama. Saya rasa saya tahu apa yang saya coba lakukan di sini, tetapi itu tidak membiarkan saya melakukannya.

EDIT: Pertanyaan saya dengan cepat ditandai sebagai sudah dijawab, namun, jawaban yang diberikan hanya menjelaskan masalah tetapi tidak benar-benar memberikan solusi. Jadi saya mengedit pertanyaan ini dengan solusi saya:

Untuk kasus khusus saya, saya tidak perlu menambahkan donor ke daftar, setidaknya tidak dalam metode abstrak. Jadi tautan Andrew Shepherd mengungkapkan bahwa masalahnya adalah, meskipun kelas saya dapat mengonversi ke antarmuka, daftar tidak bisa. Jadi sekarang saya menyampaikan daftar hanya-baca, yang diterima kompilator:

public interface IPersonOfInterest
{ 
    //code requiring certain info to exist
}    
public virtual class PersonOfInterest : IPersonOfInterest
{
    //Changed to IReadOnlyList<IPersonOfInterest>, instead of List<IPersonOfInterest>:
    public string[] GetBigPersonsInfo(IReadOnlyList<IPersonOfInterest> FromList)
    {
        return new string[] { };
    }
}

public class BigDonors : PersonOfInterest
{
    public List<BigDonor> SuchDonors = new List<BigDonor>();    
    public void GimmeDemInfos()
    {
        //Added .AsReadOnly(), and it now compiles:
        string[] GetInfo = GetBigPersonsInfo(SuchDonors.AsReadOnly());
    }
}

Jawaban

LajosArpad Dec 14 2020 at 07:08

Anda telah mengidentifikasi tujuan antarmuka dengan benar. Anda perlu menggunakan List<IPersonOfInterest>, karena sesuai dengan deskripsi.

Pendeknya

BigDonordiwarisi IPersonOfInterest, tapi List<BigDonor>BUKAN diwarisi dari List<IPersonOfInterest>. Ini berarti Anda harus List<IPersonOfInterest>dilewati, tetapi Anda akan memiliki kesempatan untuk menambahkan BigDonorelemen ke Daftar itu.