C# 为什么不是';数组是否为泛型类型?
C# 为什么不是';数组是否为泛型类型?,c#,generics,types,language-design,C#,Generics,Types,Language Design,数组声明为: public abstract class Array : ICloneable, IList, ICollection, IEnumerable { 我想知道为什么不是: public partial class Array<T> : ICloneable, IList<T>, ICollection<T>, IEnumerable<T> { 公共部分类数组 :ICloneable、IList、ICollecti
数组
声明为:
public abstract class Array
: ICloneable, IList, ICollection, IEnumerable {
我想知道为什么不是:
public partial class Array<T>
: ICloneable, IList<T>, ICollection<T>, IEnumerable<T> {
公共部分类数组
:ICloneable、IList、ICollection、IEnumerable{
数组
派生?例如
public partial class Array: Array<object> {
公共部分类数组:数组{
Array是一种历史类型,可以追溯到没有泛型的时候 今天,让
数组
,然后是数组
,然后是特定的类;)是有意义的
因此,我想知道为什么不是:
原因是C#的第一个版本中没有泛型
但我自己也不知道问题出在哪里
问题是它会破坏大量使用数组
类的代码。C#不支持多重继承,所以像这样的行
Array ary = Array.Copy(.....);
int[] values = (int[])ary;
会被打破的
如果微软从头开始重新制作C#和.NET,那么将
Array
制作成一个泛型类可能没有问题,但事实并非如此。[Update,new insights,它觉得到目前为止缺少了一些东西]
关于先前的答复:
- 数组和其他类型一样是协变的。你可以用协变实现像“object[]foo=new string[5];”这样的东西,所以这不是原因
- 兼容性可能是不重新考虑设计的原因,但我认为这也不是正确的答案
注意,基本对象和基本数组都不是面向对象语言的要求。C++是这个例子的完美例子。没有这些基本构造的基本类型的警告不能使用反射来使用数组或对象。对于那些用来制作对象的对象,使对象“感觉自然”。事实上,没有数组基类同样不可能实现Foo——Foo虽然使用频率不高,但对范例来说同样重要
因此,在没有数组基类型但有丰富的运行时类型(特别是反射)的情况下使用C#是不可能的 所以更多的细节 在哪里使用数组以及为什么使用数组 对于数组这样的基本类型,有一个基本类型用于很多事情,这是有充分理由的:- 简单数组
T[]
,就像他们使用List
一样。确切地说,两者都实现了一组通用的接口:IList
,ICollection
,IEnumerable
,IList
,ICollection
和IEnumerable
如果你知道这一点,你可以很容易地创建一个数组。我们也都知道这是真的,这并不令人兴奋,所以我们继续
- 创建收藏。
- 编组。
for (Foo *foo = beginArray; foo != endArray; ++foo)
{
// use *foo -> which is the element in the array of Foo
}
array.GetType().GetMethod("GetLength").Invoke(array, 0); // don't...
((Array)someArray).GetLength(0); // do!
基本上,这会在数组的开始处设置一个指针,并递增指针(使用sizeof(Foo)字节),直到它到达数组的结尾。元素在*Foo处检索,它获取指针“Foo”指向的元素
请再次注意,有值类型和引用类型。您真的不希望MyArray将所有内容都存储为一个对象。实现MyArray要复杂得多
一些细心的读者可以在这里指出一个事实,这里并不真正需要数组,这是真的。你需要一个Foo类型的连续元素块,如果它是值类型,它必须作为值类型的(字节表示)存储在块中
- 多维数组
int[,] foo2 = new int[2, 3];
foreach (var type in foo2.GetType().GetInterfaces())
{
Console.WriteLine("{0}", type.ToString());
}
Strong type刚从窗口消失,你最终得到了集合类型IList
,ICollection
和IEnumerable
。嘿,那么我们应该如何获得大小呢?当使用数组基类时,我们可以
((Array)someArray).GetLength(0); // do!
Mammoth[] mammoths = new Mammoth[10];
Animal[] animals = mammoths; // Covariant conversion
animals[1] = new Giraffe(); // Run-time exception
Array<Mammoth> mammoths = new Array<Mammoth>(10);
Array<Animal> animals = mammoths; // Not allowed.
IEnumerable<Animals> animals = mammoths; // Covariant conversion
ICollection<Mammoth> collection = new Mammoth[10]; // Cast to interface type
collection.Add(new Mammoth()); // Run-time exception
ICollection<Mammoth> mammoths = new Array<Mammoth>(10);
ICollection<Animal> animals = mammoths; // Not allowed
interface IList<out T> : ICollection<T>
{
T this[int index] { get; }
int IndexOf(object value);
}
interface ICollection<out T> : IEnumerable<T>
{
int Count { get; }
bool Contains(object value);
}
Array<Mammoth> mammoths = new Array<Mammoth>(10);
IList<Animals> animals = mammoths; // Covariant conversion