你们看这段代码就不要索引符

时间:2022-03-23 20:14:23
你们看这段代码就不需要索引符  照样可以像数组一样运行  索引符是多余的  你们看这两段代码 相比较一下就知道了:
你们说在程序里添加索引符有必要吗?
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace delete
{
    class Program
    {
        static void Main(string[] args)
        {
             IList f = new Animals();
            f.Add(1); f.Add(2); f[0] = 7;
            foreach (int c in f)
                Console.WriteLine(c);
            Console.WriteLine("{0} {1}", f[0], f[1]);
            
            
        }
    }
    public class Animal
    { }
    public class Animals : CollectionBase
    {
        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }
        
    }
}
----------------------------------------------------------------------------------------
这一段把索引符去掉则会出错
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace delete
{
    class Program
    {
        static void Main(string[] args)
        {
            Animals a = new Animals();
            a.Add(1); a.Add(2);
            foreach (int c in a)
                Console.WriteLine(c);
            a[0] = 3;
            foreach (int c in a)
                Console.WriteLine(c);
            
        }
    }
    public class Animal
    { }
    public class Animals : CollectionBase
    {
        public void Add(int newAnimal)
        {
            List.Add(newAnimal);                                                  
            
        }
         public int this[int index]
        {
            get
            {
                return (int)List[index];
            }
            set
            {
                List[index] = value;
            }
        }
    }
}

22 个解决方案

#1


        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

#2


你碰到了 .net 在15年前从c++里边继承来的一个糟粕,加上所谓“索引符”的使用,混淆在一起了。

当你写
    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#也并没有按照面向对象的规范去定义,也是个特例。

#3


嗯,重新看了一下 CollectionBase 定义的源代码,它的定义是这样的
[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
 

它在最后的

#4


它定义了几个父类接口方法不能直接使用,必须通过父类类型间接调用。我上面说的“现在c#版本对索引操作符是不支持继承的”这个可能是不对的(你另外在测试一下),至少这里CollectionBase 定义中明确定义了必须通过 IList 来调用。

#5


引用 1 楼 crystal_lz 的回复:
        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

#6


奇怪,我明明输入且提交的内容,csdn服务器刷新页面之后怎么直接丢掉了内容呢?!



不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。

如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL  你们看这段代码就不要索引符

#7


引用 4 楼 sp1234 的回复:
它定义了几个父类接口方法不能直接使用,必须通过父类类型间接调用。我上面说的“现在c#版本对索引操作符是不支持继承的”这个可能是不对的(你另外在测试一下),至少这里CollectionBase 定义中明确定义了必须通过 IList 来调用。

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;
            }
        }
    }
你这个代码是从哪里看到的?

#8


操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了

#9


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


我问一下  以专业开发人员为伍的代码是从哪里查到的  就是3楼的代码

#10


引用 5 楼 weikeli19 的回复:
Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

#11


引用 10 楼 crystal_lz 的回复:
Quote: 引用 5 楼 weikeli19 的回复:

Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

会  你试验一下不就知道了嘛

#12


1. 直接下载.NET Framework源代码( 下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。

VS 的联机帮助里也可看到

#13


引用 11 楼 weikeli19 的回复:
Quote: 引用 10 楼 crystal_lz 的回复:

Quote: 引用 5 楼 weikeli19 的回复:

Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

会  你试验一下不就知道了嘛

你是从哪里判断它执行了的?。。。就应为 你确实添加进去了数据吗?。。
你访问当的 压根就不是 Animals.Add 而是 IList.Add 
如果上面的代码 真的是执行了的话 那就只能得到一个异常 *exception 栈溢出 很简单 那代码看上去就和死递归 没什么区别

#14


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


你说的这句话我理解不了 f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
怎么是枚举啊 enum啊? 怎么会是枚举呢

#15


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了

还是你说的此枚举非彼枚举?

#16


引用 12 楼 xuzuning 的回复:
1. 直接下载.NET Framework源代码( 下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。

VS 的联机帮助里也可看到

在吗?  你说的此枚举非彼枚举是吗?

#17


你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?

#18


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?


泛型没学过 我没钻牛角尖  这是我学习应有的态度啊

#19


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?


是不是此枚举非彼枚举  ?

#20


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?

你现在只要回答是还是不是就行了

#21


引用 14 楼 weikeli19 的回复:
Quote: 引用 8 楼 xuzuning 的回复:

操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


你说的这句话我理解不了 f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
怎么是枚举啊 enum啊? 怎么会是枚举呢

他说的枚举是一个动词,你说的enum是一种数据类型

#22


当然是不行!
泛型没学过的话,这个应该没有问题了吧?
        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]; }
            }
        }
我想,你是在这里被绕住了

#1


        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

#2


你碰到了 .net 在15年前从c++里边继承来的一个糟粕,加上所谓“索引符”的使用,混淆在一起了。

当你写
    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#也并没有按照面向对象的规范去定义,也是个特例。

#3


嗯,重新看了一下 CollectionBase 定义的源代码,它的定义是这样的
[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
 

它在最后的

#4


它定义了几个父类接口方法不能直接使用,必须通过父类类型间接调用。我上面说的“现在c#版本对索引操作符是不支持继承的”这个可能是不对的(你另外在测试一下),至少这里CollectionBase 定义中明确定义了必须通过 IList 来调用。

#5


引用 1 楼 crystal_lz 的回复:
        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

#6


奇怪,我明明输入且提交的内容,csdn服务器刷新页面之后怎么直接丢掉了内容呢?!



不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。

如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL  你们看这段代码就不要索引符

#7


引用 4 楼 sp1234 的回复:
它定义了几个父类接口方法不能直接使用,必须通过父类类型间接调用。我上面说的“现在c#版本对索引操作符是不支持继承的”这个可能是不对的(你另外在测试一下),至少这里CollectionBase 定义中明确定义了必须通过 IList 来调用。

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;
            }
        }
    }
你这个代码是从哪里看到的?

#8


操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了

#9


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


我问一下  以专业开发人员为伍的代码是从哪里查到的  就是3楼的代码

#10


引用 5 楼 weikeli19 的回复:
Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

#11


引用 10 楼 crystal_lz 的回复:
Quote: 引用 5 楼 weikeli19 的回复:

Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

会  你试验一下不就知道了嘛

#12


1. 直接下载.NET Framework源代码( 下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。

VS 的联机帮助里也可看到

#13


引用 11 楼 weikeli19 的回复:
Quote: 引用 10 楼 crystal_lz 的回复:

Quote: 引用 5 楼 weikeli19 的回复:

Quote: 引用 1 楼 crystal_lz 的回复:

        public void Add(int newAnimal)
        {
            
            IList d = new Animals();
            d.Add(newAnimal);
        }

你确定你的第一段代码是对的 ?、、、、、、、

我确定 不信你可以上机实验一下

那他会执行吗?。。。

会  你试验一下不就知道了嘛

你是从哪里判断它执行了的?。。。就应为 你确实添加进去了数据吗?。。
你访问当的 压根就不是 Animals.Add 而是 IList.Add 
如果上面的代码 真的是执行了的话 那就只能得到一个异常 *exception 栈溢出 很简单 那代码看上去就和死递归 没什么区别

#14


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


你说的这句话我理解不了 f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
怎么是枚举啊 enum啊? 怎么会是枚举呢

#15


引用 8 楼 xuzuning 的回复:
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了

还是你说的此枚举非彼枚举?

#16


引用 12 楼 xuzuning 的回复:
1. 直接下载.NET Framework源代码( 下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。

VS 的联机帮助里也可看到

在吗?  你说的此枚举非彼枚举是吗?

#17


你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?

#18


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?


泛型没学过 我没钻牛角尖  这是我学习应有的态度啊

#19


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?


是不是此枚举非彼枚举  ?

#20


引用 17 楼 xuzuning 的回复:
你又在钻牛角尖了吧?
如果 a = new List<int>() {1,2,3}
那你就可以 a[0]、a[1]、a[2] 访问他的成员

如果 
class A
{
  List<int> a = new List<int>() {1,2,3};
}
a = new A()
你还可以 a[0]、a[1]、a[2] 这样访问吗?

你现在只要回答是还是不是就行了

#21


引用 14 楼 weikeli19 的回复:
Quote: 引用 8 楼 xuzuning 的回复:

操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样

Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了


你说的这句话我理解不了 f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
怎么是枚举啊 enum啊? 怎么会是枚举呢

他说的枚举是一个动词,你说的enum是一种数据类型

#22


当然是不行!
泛型没学过的话,这个应该没有问题了吧?
        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]; }
            }
        }
我想,你是在这里被绕住了