【发布时间】:2019-08-06 11:20:56
【问题描述】:
我对 C# 接口有点陌生,对于继承接口列表问题的扩展方法,我遇到了一个相当尴尬的解决方案。示例接口如下所示:
public interface IData
{
int Value { get; set; }
}
public interface IDataWithName : IData
{
string Name { get; set; }
}
public interface IDataContainer
{
IList<IData> DataList { get; set; }
}
public interface IDataWithNameContainer : IDataContainer
{
new IList<IDataWithName> DataList { get; set; }
}
使用扩展方法:
public static class ExtensionMethod
{
public static int CountNumberOfIDataItems(this IDataContainer i)
{
return i.DataList.Count();
}
}
实现这些接口时,IList DataList 和IList IDataContainer.DataList 都需要实现。虽然这是可能的,但生成的代码并不优雅:
public class DataNameImplimentatioFixed : IDataWithNameContainer
{
public IList<IDataWithName> DataList { get; set; }
IList<IData> IDataContainer.DataList
{
get => new List<IData>(DataList);
set
{
DataList = new List<IDataWithName>();
foreach (IDataWithName _dataLoop in value) { DataList.Add(_dataLoop); }
}
}
}
每次调用扩展时复制列表可能会导致一些性能问题,并且需要额外检查 IDataContainer 上的任何其他方法不会尝试添加从 IData 但不是从 IDataWithName 继承的类。
感觉应该有更好的方法来使用扩展方法,这样就不会那么容易受到未来扩展问题的影响。我能想到的最佳解决方案是将 IList DataList 从 IDataContainer 中取出,并为每个包含列表的类提供单独的扩展方法。
谁能想出比这更好的解决方案?
【问题讨论】:
-
扩展方法不是接口或类的一部分,因此不适用继承。 您的 问题与 hiding
DataList在 IDataWithNameContainer 中有关。这与扩展方法无关,是在相关接口中使用相同成员名称的设计的问题 -
这可以通过使两个容器接口通用并在 IDataWithNameContainer 中使用更严格的类型约束来解决
-
关于扩展方法的好点只是问题出现的地方,而不是问题所在的位置。我会从标签和标题中删除它。
标签: c# inheritance interface