【发布时间】: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<BigDonors>更改为List<IPersonOfInterest> -
@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