在.NET中,使用"foreach"迭代IEnumerable的实例会创建一个副本吗?那么我是否应该使用"for"而不是"foreach"?
我写了一些代码来证明这一点:
struct ValueTypeWithOneField
{
private Int64 field1;
}
struct ValueTypeWithFiveField
{
private Int64 field1;
private Int64 field2;
private Int64 field3;
private Int64 field4;
private Int64 field5;
}
public class Program
{
static void Main(string[] args)
{
Console.WriteLine("one field");
Test<ValueTypeWithOneField>();
Console.WriteLine("-----------");
Console.WriteLine("Five field");
Test<ValueTypeWithFiveField>();
Console.ReadLine();
}
static void Test<T>()
{
var test = new List<T>();
for (int i = 0; i < 5000000; i++)
{
test.Add(default(T));
}
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 5; …Run Code Online (Sandbox Code Playgroud) IList<T>不继承IList那里IEnumerable<out T>继承IEnumerable.
如果out修正是唯一的原因,那么为什么大多数的实施IList<T>(例如Collection<T>,List<T>)实现IList接口.
所以任何人都可以说好,如果那些陈述对于所有的实现都是真的,IList<T>那么IList在必要时直接将其强制转换.但问题是虽然IList<T>没有继承IList所以不能保证每个IList<T>对象都是IList.
此外,使用IList<object>显然不是解决方案,因为没有out修饰符泛型不能分配给较少的继承类; 并且创建List的新实例在这里不是解决方案,因为有人可能想要实际引用IList<T>作为IList指针; 并且使用List<T>insteed IList<T>实际上是一种糟糕的编程习惯,并不能用于所有目的.
如果.NET希望提供灵活性,每个实现IList<T>都不应该有非泛型实现的合同(即IList)那么为什么他们没有保留另一个实现泛型和非泛型版本的接口,并没有暗示所有具体的想要签订通用和非遗传项目的类应通过该接口签订合同.
发生铸造同样的问题ICollection<T>,以ICollection及IDictionary<TKey, TValue>对IDictionary.
继承是C#中的传递关系吗?
我问,因为我不明白为什么IList<T>器具ICollection<T>和IEnumerable<T>作为ICollection<T>已经实现IEnumerable<T>
谢谢你为我澄清这一点.
去实现细节,我看到Array类的实现
public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
Run Code Online (Sandbox Code Playgroud)
IList接口的实现读作
public interface IList : ICollection, IEnumerable
Run Code Online (Sandbox Code Playgroud)
我的问题是,不将Array类自动执行ICollection和IEnumerable它实现的那一刻IList?为什么这些明确实施?
出于好奇,通用List <>实现非通用接口IList的原因是什么?
示例代码
IList<int> list = new List<int>();
list.Add(1);
//compiles but ArgumentException thrown at run time
((IList)list).Add(new object());
Run Code Online (Sandbox Code Playgroud) List<T> 派生自以下接口:
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
Run Code Online (Sandbox Code Playgroud)
我只是想知道为什么它需要所有这些接口(在类声明中)?
IList本身已经从派生ICollection<T>,IEnumerable<T>UND IEnumerable.
那么为什么以下不够呢?
public class List<T> : IList<T>, IList
Run Code Online (Sandbox Code Playgroud)
我希望你能解决我的困惑.
我对C#中接口的继承语法有点不清楚.
例如:
public interface IFoo
{
}
public interface IBar : IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
这有什么区别:
public interface IQux : IBar
{
}
Run Code Online (Sandbox Code Playgroud)
还有这个:
public interface IQux : IBar, IFoo
{
}
Run Code Online (Sandbox Code Playgroud)
或者,对于一个真实世界的例子,为什么ICollection<T>声明如下:
public interface ICollection<T> : IEnumerable<T>, IEnumerable
Run Code Online (Sandbox Code Playgroud)
而不是这个:
public interface ICollection<T> : IEnumerable<T>
Run Code Online (Sandbox Code Playgroud)
鉴于IEnumerable<T>已经继承了IEnumerable?
我知道StackOverflow上出现了完全相同的问题,但它并没有完全回答我的问题.
如果ICollection<T>实现IEnumerable<T>,扩展IEnumerable,为什么来自Microsoft的程序员添加IEnumerable作为实现的接口ICollection<T>?
是不是完全(语义和实现方式)与简单写作相同ICollection<T> : IEnumerable<T>?
c# ×8
.net ×4
generics ×2
arrays ×1
collections ×1
foreach ×1
generic-list ×1
ilist ×1
performance ×1
value-type ×1