如下代码:
public interface ISomeData { IEnumerable<string> Data { get; } } public class MyData : ISomeData { private List<string> m_MyData = new List<string>(); public List<string> Data { get { return m_MyData; } } }
产生以下错误:
错误CS0738:“ InheritanceTest.MyData”未实现接口成员“ InheritanceTest.ISomeData.Data”。’InheritanceTest.MyData.Data’无法实现’InheritanceTest.ISomeData.Data’,因为它没有匹配的返回类型’System.Collections.Generic.IEnumerable’。
由于List 实现IEnumerable ,因此人们会认为我的类将实现该接口。有人可以解释不进行编译的基本原理吗?
如我所见,有两种可能的解决方案:
现在假设我还有以下代码:
public class ConsumerA { static void IterateOverCollection(ISomeData data) { foreach (string prop in data.MyData) { /*do stuff*/ } } } public class ConsumerB { static void RandomAccess(MyData data) { data.Data[1] = "this line is invalid if MyPropList return an IEnumerable<string>"; } }
我可以更改接口以要求实现IList(选项1),但这限制了可以实现该接口的人员以及可以传递给ConsumerA的类的数量。或者,我可以更改实现(类MyData),以便它返回IEnumerable而不是列表(选项2),但随后必须重写ConsumerB。
除非有人能启发我,否则这似乎是C#的缺点。
不幸的是,返回类型必须匹配。您正在寻找的被称为“返回类型协方差”,而C#不支持。
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=90909
C#编译器团队的高级开发人员Eric Lippert在他的博客中提到,他们不打算支持返回类型协方差。
“这种差异称为“返回类型协方差”。正如我在本系列文章的前面部分提到的那样,(a)该系列与这种差异无关,并且(b)我们没有计划在C#。 ”
http://blogs.msdn.com/ericlippert/archive/2008/05/07/covariance-and- contravariance-part-twelve-to-infinity-but-not- beyond.aspx
值得阅读Eric关于协方差和相反方差的文章。
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx