IList接口既然继承了ICollection接口,为什么还要继承IEnumerable接口..

sakiwer 2009-12-17 03:40:46
IList接口既然继承了ICollection接口,为什么还要继承IEnumerable接口..如题...
...全文
510 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
浪长街 2012-01-31
  • 打赏
  • 举报
回复
我今天刚刚发现这个问题,在网上找到答案了,请看看这
http://www.cnblogs.com/allenlooplee/archive/2004/11/16/64394.html
fz069820 2011-09-05
  • 打赏
  • 举报
回复
不错不错·~~ 这个问题我也想了很久了。。。
wartim 2009-12-17
  • 打赏
  • 举报
回复
我试了下,
foreach调用的是ICollection的迭代器,返回的是A数组内容
linq调用的是直接继承的IEnumerable的迭代器,返回的是B数组内容


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace WindowsFormsApplication17
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();

X x = new X();

foreach (int i in x) // A
MessageBox.Show(i.ToString());

var y = from int i in x select i;
foreach (int i in y) // B
MessageBox.Show(i.ToString());
}
}

class X : ICollection, IEnumerable
{
public int[] A = { 1, 2, 3 };
public int[] B = { 4, 5, 6 };

#region ICollection 成员

public void CopyTo(Array array, int index)
{
throw new NotImplementedException();
}

public int Count
{
get { throw new NotImplementedException(); }
}

public bool IsSynchronized
{
get { throw new NotImplementedException(); }
}

public object SyncRoot
{
get { throw new NotImplementedException(); }
}

#endregion

#region IEnumerable 成员

public IEnumerator GetEnumerator()
{
return A.GetEnumerator();
}

#endregion

#region IEnumerable 成员

IEnumerator IEnumerable.GetEnumerator()
{
return B.GetEnumerator();
}

#endregion
}
}
guilipan 2009-12-17
  • 打赏
  • 举报
回复
真正的原因是为了让人知道ILIST实现哪些接口,不然用户需要自己手动递归查找才知道继承谁实现谁,.NET FRAMEWORK的TEAM当初就是基于这个目的才这样做的,这样一目了然,不是很好吗。
vrhero 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yuxuanji 的回复:]
个人认为偏向于符合接口隔离原则
不知道我说的对不对
[/Quote]
这是个可以接受的解释...我在CLR中还找到更多这样的例子,虽然这些都和隔离没有直接关系(基接口已经继承了不存在隔离),但这样做接口描述更清晰,性能上我想也会有帮助(不用查找继承链)...
cuike519 2009-12-17
  • 打赏
  • 举报
回复
下面是IList的源代码,你看到的是Reflector反射的代码。

ICollection继承了IEnumerable接口,下面有源代码为证:

/*============================================================
**
** Interface: IList
**
**
** Purpose: Base interface for all Lists.
**
**
===========================================================*/
namespace System.Collections {

using System;
// An IList is an ordered collection of objects. The exact ordering
// is up to the implementation of the list, ranging from a sorted
// order to insertion order.
[System.Runtime.InteropServices.ComVisible(true)]
public interface IList : ICollection
{
// Interfaces are not serializable
// The Item property provides methods to read and edit entries in the List.
Object this[int index] {
get;
set;
}

// Adds an item to the list. The exact position in the list is
// implementation-dependent, so while ArrayList may always insert
// in the last available location, a SortedList most likely would not.
// The return value is the position the new element was inserted in.
int Add(Object value);

// Returns whether the list contains a particular item.
bool Contains(Object value);

// Removes all items from the list.
void Clear();

bool IsReadOnly
{ get; }


bool IsFixedSize
{
get;
}


// Returns the index of a particular item, if it is in the list.
// Returns -1 if the item isn't in the list.
int IndexOf(Object value);

// Inserts value into the list at position index.
// index must be non-negative and less than or equal to the
// number of elements in the list. If index equals the number
// of items in the list, then value is appended to the end.
void Insert(int index, Object value);

// Removes an item from the list.
void Remove(Object value);

// Removes the item at position index.
void RemoveAt(int index);
}
}
LutzMark 2009-12-17
  • 打赏
  • 举报
回复
个人认为偏向于符合接口隔离原则
不知道我说的对不对
LutzMark 2009-12-17
  • 打赏
  • 举报
回复
参照 ArrayList : IList, ICollection, IEnumerable, ICloneable
sakiwer 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vrhero 的回复:]
不好意思,想当然了...看了一下MSDN也没明确的解释...

我想应该跟foreach语句有关系,MSDN中说明了“必须实现IEnumerable以支持foreach语义”...我想可能沿继承链查找IEnumerable接口会影响foreach语句的性能...
[/Quote]

接口函数不是都存在与虚表么...它这么2个IEnumerable...虚表里怎么识别的..不明白..
sakiwer 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 gomoku 的回复:]
我怀疑这是MS处于性能考虑把接口层次平坦化。

编译以下例子:
namespace ClassLibrary1
{
    interface IA { }
    interface IB : IA { }
    interface IC : IB { }

    public class Class1 : IC
    {
    }
}

产生的IL代码:
.class interface private abstract auto ansi ClassLibrary1.IC
      implements ClassLibrary1.IB,
                  ClassLibrary1.IA
{
}

其他项目看到:
namespace ClassLibrary1
{
    public class Class1 : IC, IB, IA
    internal interface IA
    internal interface IB : IA
    internal interface IC :IB, IA
}
[/Quote]

namespace ClassLibrary1
{
public class Class1 : IC
internal interface IA
internal interface IB : IA
internal interface IC :IB, IA
}

namespace ClassLibrary1
{
public class Class1 : IC
internal interface IA
internal interface IB : IA
internal interface IC :IB
}

编译后 IL代码 是一样的..
.class interface private abstract auto ansi ClassLibrary1.IC
implements ClassLibrary1.IB,
ClassLibrary1.IA
{
}
这在性能上有什么区别么..不明白..
vrhero 2009-12-17
  • 打赏
  • 举报
回复
不好意思,想当然了...看了一下MSDN也没明确的解释...

我想应该跟foreach语句有关系,MSDN中说明了“必须实现IEnumerable以支持foreach语义”...我想可能沿继承链查找IEnumerable接口会影响foreach语句的性能...
gomoku 2009-12-17
  • 打赏
  • 举报
回复
我怀疑这是MS处于性能考虑把接口层次平坦化。

编译以下例子:
namespace ClassLibrary1
{
interface IA { }
interface IB : IA { }
interface IC : IB { }

public class Class1 : IC
{
}
}

产生的IL代码:
.class interface private abstract auto ansi ClassLibrary1.IC
implements ClassLibrary1.IB,
ClassLibrary1.IA

{
}

其他项目看到:
namespace ClassLibrary1
{
public class Class1 : IC, IB, IA
internal interface IA
internal interface IB : IA
internal interface IC : IB, IA
}


sakiwer 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 vrhero 的回复:]
引用 1 楼 zhounet 的回复:
因为ICollection继承了IEnumerable了,所以IList也要继承IEnumerable并实现它的成员

不是这个原因...

因为ICollection的IEnumerable接口是显式实现的,IList继承的IEnumerable是独立的,所以它有两个IEnumerable接口...其他继承自ICollection的接口如果需要IEnumerable接口也会这样做...
[/Quote]

[ComVisible(true)]
public interface ICollection : IEnumerable
{
// Methods
void CopyTo(Array array, int index);

// Properties
int Count { get; }
bool IsSynchronized { get; }
object SyncRoot { get; }
}
并没有显式实现啊...如果它有2个IEnumerable接口..那么.net是如何管理的呢..不会冲突么?



vrhero 2009-12-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhounet 的回复:]
因为ICollection继承了IEnumerable了,所以IList也要继承IEnumerable并实现它的成员
[/Quote]
不是这个原因...

因为ICollection的IEnumerable接口是显式实现的,IList继承的IEnumerable是独立的,所以它有两个IEnumerable接口...其他继承自ICollection的接口如果需要IEnumerable接口也会这样做...
sakiwer 2009-12-17
  • 打赏
  • 举报
回复
public interface IList : ICollection, IEnumerable{}
public interface ICollection : IEnumerable{}

看这个..我的意思是 它重复了 ICollection内部 就已经继承了IEnumerable接口..
zhounet 2009-12-17
  • 打赏
  • 举报
回复
因为ICollection继承了IEnumerable了,所以IList也要继承IEnumerable并实现它的成员

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧