C # Невозможно преобразовать из класса в интерфейс [дубликат]

Dec 14 2020

Я новичок в использовании интерфейсов, но после прочтения я подумал, что идея интерфейсов заключается в том, что класс, производный от интерфейса, будет приниматься везде, где принимается интерфейс. Вот мой код:

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
    }
}

Как видите, BigDonorsпроисходит от IPersonOfInterestинтерфейса. Так почему же он выдает ошибку компилятора, говоря, что список BigDonorне может быть преобразован в список IPersonOfInterest? Я понимаю, что это не одно и то же. Думаю, я знаю, что пытаюсь здесь сделать, но это мне не позволяет.

РЕДАКТИРОВАТЬ: Мой вопрос был быстро отмечен как уже отвеченный, однако предоставленный ответ только объясняет проблему, но на самом деле не дает решения. Итак, я редактирую этот вопрос своим решением:

В моем конкретном случае мне не нужно иметь возможность добавлять доноров в список, по крайней мере, не в абстрактном методе. Таким образом, ссылка Эндрю Шепарда показала, что проблема заключалась в том, что, хотя мой класс мог преобразовывать в интерфейс, список - нет. Итак, теперь я передаю список только для чтения, который принимает компилятор:

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());
    }
}

Ответы

LajosArpad Dec 14 2020 at 07:08

Вы правильно определили назначение интерфейсов. Вам нужно использовать List<IPersonOfInterest>, потому что это соответствует описанию.

Коротко

BigDonorунаследовано IPersonOfInterest, но List<BigDonor>НЕ было унаследовано от List<IPersonOfInterest>. Это означает, что вам нужно List<IPersonOfInterest>будет пройти, но у вас будет возможность добавлять BigDonorэлементы в этот список.