111,128
社区成员
发帖
与我相关
我的任务
分享
[Serializable, ComVisible(true), __DynamicallyInvokable]
public abstract class CollectionBase : IList, ICollection, IEnumerable
{
// Fields
private ArrayList list;
// Methods
protected CollectionBase()
{
this.list = new ArrayList();
}
protected CollectionBase(int capacity)
{
this.list = new ArrayList(capacity);
}
[__DynamicallyInvokable]
public void Clear()
{
this.OnClear();
this.InnerList.Clear();
this.OnClearComplete();
}
[__DynamicallyInvokable]
public IEnumerator GetEnumerator()
{
return this.InnerList.GetEnumerator();
}
protected virtual void OnClear()
{
}
protected virtual void OnClearComplete()
{
}
protected virtual void OnInsert(int index, object value)
{
}
protected virtual void OnInsertComplete(int index, object value)
{
}
protected virtual void OnRemove(int index, object value)
{
}
protected virtual void OnRemoveComplete(int index, object value)
{
}
protected virtual void OnSet(int index, object oldValue, object newValue)
{
}
protected virtual void OnSetComplete(int index, object oldValue, object newValue)
{
}
protected virtual void OnValidate(object value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
}
[__DynamicallyInvokable]
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this.Count))
{
throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
object obj2 = this.InnerList[index];
this.OnValidate(obj2);
this.OnRemove(index, obj2);
this.InnerList.RemoveAt(index);
try
{
this.OnRemoveComplete(index, obj2);
}
catch
{
this.InnerList.Insert(index, obj2);
throw;
}
}
void ICollection.CopyTo(Array array, int index)
{
this.InnerList.CopyTo(array, index);
}
int IList.Add(object value)
{
this.OnValidate(value);
this.OnInsert(this.InnerList.Count, value);
int index = this.InnerList.Add(value);
try
{
this.OnInsertComplete(index, value);
}
catch
{
this.InnerList.RemoveAt(index);
throw;
}
return index;
}
bool IList.Contains(object value)
{
return this.InnerList.Contains(value);
}
int IList.IndexOf(object value)
{
return this.InnerList.IndexOf(value);
}
void IList.Insert(int index, object value)
{
if ((index < 0) || (index > this.Count))
{
throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
this.OnValidate(value);
this.OnInsert(index, value);
this.InnerList.Insert(index, value);
try
{
this.OnInsertComplete(index, value);
}
catch
{
this.InnerList.RemoveAt(index);
throw;
}
}
void IList.Remove(object value)
{
this.OnValidate(value);
int index = this.InnerList.IndexOf(value);
if (index < 0)
{
throw new ArgumentException(Environment.GetResourceString("Arg_RemoveArgNotFound"));
}
this.OnRemove(index, value);
this.InnerList.RemoveAt(index);
try
{
this.OnRemoveComplete(index, value);
}
catch
{
this.InnerList.Insert(index, value);
throw;
}
}
// Properties
[ComVisible(false)]
public int Capacity
{
get
{
return this.InnerList.Capacity;
}
set
{
this.InnerList.Capacity = value;
}
}
public int Count
{
[__DynamicallyInvokable]
get
{
if (this.list != null)
{
return this.list.Count;
}
return 0;
}
}
protected ArrayList InnerList
{
get
{
if (this.list == null)
{
this.list = new ArrayList();
}
return this.list;
}
}
protected IList List
{
get
{
return this;
}
}
bool ICollection.IsSynchronized
{
get
{
return this.InnerList.IsSynchronized;
}
}
object ICollection.SyncRoot
{
get
{
return this.InnerList.SyncRoot;
}
}
bool IList.IsFixedSize
{
get
{
return this.InnerList.IsFixedSize;
}
}
bool IList.IsReadOnly
{
get
{
return this.InnerList.IsReadOnly;
}
}
object IList.this[int index]
{
get
{
if ((index < 0) || (index >= this.Count))
{
throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
return this.InnerList[index];
}
set
{
if ((index < 0) || (index >= this.Count))
{
throw new ArgumentOutOfRangeException("index", Environment.GetResourceString("ArgumentOutOfRange_Index"));
}
this.OnValidate(value);
object oldValue = this.InnerList[index];
this.OnSet(index, oldValue, value);
this.InnerList[index] = value;
try
{
this.OnSetComplete(index, oldValue, value);
}
catch
{
this.InnerList[index] = oldValue;
throw;
}
}
}
}
Collapse Methods
它在最后的 public class Animals : CollectionBase
{
//public void Add(int newAnimal)
//{
// IList d = new Animals();
// d.Add(newAnimal);
//}
}也就是把所谓 Add 注释掉,第一段照样可以执行。
面向对象的分析和设计技术中,实际上应该避免这种用 Add 来篡改 Add 的行为。Add 要么用 override 方式来重写父类的方法,要么(当父类不允许子类重写此方法时)就应该编译时报错。而.net 最初从c++中恰好继承了这个“可用完全无关的 Add 方法来重载父类Add方法”的特性,这本身是违反面向对象设计原则的,是容易让人产生误解的。
接下来,对于“索引符”,c#编译器要求必须是你声明的变量类型本身就定义有索引操作定义,而不管类型的父类/接口有没有可用的操作定义。因为这个[ ] 是一个语法糖,是c#的特性而不是 .net 的特性。(vb.net 中另外定义了其它语法形式的索引操作定义)
因此在这个索引操作符方面,其实c#也并没有按照面向对象的规范去定义,也是个特例。 static void Main(string[] args)
{
int[] a = { 1, 2, 3, 4, 5 }; //这是一个数组
Console.WriteLine("{0} {1}", a[0], a[1]); //所以你可以用下标访问
var b = new B(); //这是一个对象
Console.WriteLine("{0} {1}", b.b[0], b.b[1]); //b.b 是公共的,所以你可以这样访问,如果是私有(保护)的,就访问不到了
Console.WriteLine("{0} {1}", b[0], b[1]); //如果没有索引器,你就不能这样访问
Console.ReadKey();
}
class B
{
public int[] b = { 1, 2, 3, 4, 5 };
public int this[int index] //索引器
{
get { return b[index]; }
}
}
我想,你是在这里被绕住了