【问题标题】:C# Cannot convert from class to interface [duplicate]C#无法从类转换为接口[重复]
【发布时间】:2020-12-13 23:56:27
【问题描述】:

我是使用接口的新手,但是在阅读之后,我认为接口的想法是从接口派生的类将在任何接受接口的地方被接受。这是我的代码:

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 的列表?我明白他们不是一回事。我想我知道我想在这里做什么,但它不允许我这样做。

编辑:我的问题很快被标记为已回答,但是,提供的答案仅解释了问题,但并没有真正给出解决方案。所以我正在用我的解决方案编辑这个问题:

对于我的特殊情况,我不需要能够将捐助者添加到列表中,至少不是在抽象方法中。所以 Andrew Shepherd 的链接显示问题在于,虽然我的类可以转换为接口,但列表不能。所以现在我传递了一个只读列表,编译器接受:

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

【问题讨论】:

  • List&lt;BigDonors&gt;更改为List&lt;IPersonOfInterest&gt;
  • @Hayden 那么我在任何试图调用诸如此类的代码时都会出错。SuchDonors[0].GimmeDemInfos()。
  • So why does it give a compiler error, saying a list of BigDonor cannot be converted to list of IPersonOfInterest? 因为它不能。您正在尝试将一盒草莓视为任何水果/蔬菜的一盒。这是有问题的 - 草莓篮将接受草莓。但是,anything 的小篮子可以带一个南瓜(这显然不适合)。编译器正确地说“我不能允许”。
  • My question was quickly marked as already answered, however, the answer provided only explains the problem but doesn't really give a solution. 它提供了多种解决方案(例如IEnumerable - 大致相当于您使用IReadOnlyList 选择的方法)。您的代码示例也无法编译。如果你愿意,你也可以删除AsReadOnly
  • 将 IReadOnlyList 添加到参数中效果很好。正如@mjwills 提到的,您不需要 .AsReadOnly()

标签: c# visual-studio interface abstract-class


【解决方案1】:

您已正确识别接口的用途。您需要使用List&lt;IPersonOfInterest&gt;,因为它符合描述。

总之

BigDonor 继承自 IPersonOfInterest,但 List&lt;BigDonor&gt; 不是继承自 List&lt;IPersonOfInterest&gt;。这意味着您将需要 List&lt;IPersonOfInterest&gt; 才能被传递,但您将有机会将 BigDonor 元素添加到该列表中。

【讨论】:

  • 那么,public List&lt;IPersonOfInterest&gt; SuchDonors = new List&lt;IPersonOfInterest&gt;(); 可以随意添加BigDonors 到列表中
  • @Ergis 完全正确!
  • @LajosArpad(或 Ergis)我认为这不是正确的解决方案。然后允许将其他类型添加到列表中,这显然不是 OP 想要的(给定属性和类的名称)。因此,这留下了两个可能可行的解决方案(根据副本)。 a) 在调用方法时创建一个新列表(即Cast&lt;&gt;.ToList())。 b) 将方法签名从List 更改为IEnumerable。 b) 可能是 OP 需要的。
猜你喜欢
  • 2017-02-06
  • 1970-01-01
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 2017-05-10
  • 1970-01-01
相关资源
最近更新 更多