你们说在程序里添加索引符有必要吗?
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);
}
你确定你的第一段代码是对的 ?、、、、、、、
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
#2
你碰到了 .net 在15年前从c++里边继承来的一个糟粕,加上所谓“索引符”的使用,混淆在一起了。
当你写
面向对象的分析和设计技术中,实际上应该避免这种用 Add 来篡改 Add 的行为。Add 要么用 override 方式来重写父类的方法,要么(当父类不允许子类重写此方法时)就应该编译时报错。而.net 最初从c++中恰好继承了这个“可用完全无关的 Add 方法来重载父类Add方法”的特性,这本身是违反面向对象设计原则的,是容易让人产生误解的。
接下来,对于“索引符”,c#编译器要求必须是你声明的变量类型本身就定义有索引操作定义,而不管类型的父类/接口有没有可用的操作定义。因为这个[ ] 是一个语法糖,是c#的特性而不是 .net 的特性。(vb.net 中另外定义了其它语法形式的索引操作定义)
因此在这个索引操作符方面,其实c#也并没有按照面向对象的规范去定义,也是个特例。
当你写
public class Animals : CollectionBase也就是把所谓 Add 注释掉,第一段照样可以执行。
{
//public void Add(int newAnimal)
//{
// IList d = new Animals();
// d.Add(newAnimal);
//}
}
面向对象的分析和设计技术中,实际上应该避免这种用 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
我确定 不信你可以上机实验一下
#6
奇怪,我明明输入且提交的内容,csdn服务器刷新页面之后怎么直接丢掉了内容呢?!
不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。
如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL
不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。
如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL
#7
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] 了
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了
#9
我问一下 以专业开发人员为伍的代码是从哪里查到的 就是3楼的代码
#10
那他会执行吗?。。。
#11
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
那他会执行吗?。。。
会 你试验一下不就知道了嘛
#12
1. 直接下载.NET Framework源代码(
下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。
VS 的联机帮助里也可看到
2. 在线查看,网址:http://referencesource.microsoft.com/ 。
VS 的联机帮助里也可看到
#13
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
那他会执行吗?。。。
会 你试验一下不就知道了嘛
你是从哪里判断它执行了的?。。。就应为 你确实添加进去了数据吗?。。
你访问当的 压根就不是 Animals.Add 而是 IList.Add
如果上面的代码 真的是执行了的话 那就只能得到一个异常 *exception 栈溢出 很简单 那代码看上去就和死递归 没什么区别
#14
操作的对象不同,自然用法上也有所不同
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
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了
还是你说的此枚举非彼枚举?
#16
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] 这样访问吗?
如果 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
你又在钻牛角尖了吧?
如果 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
你又在钻牛角尖了吧?
如果 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
你又在钻牛角尖了吧?
如果 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
操作的对象不同,自然用法上也有所不同
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);
}
你确定你的第一段代码是对的 ?、、、、、、、
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
#2
你碰到了 .net 在15年前从c++里边继承来的一个糟粕,加上所谓“索引符”的使用,混淆在一起了。
当你写
面向对象的分析和设计技术中,实际上应该避免这种用 Add 来篡改 Add 的行为。Add 要么用 override 方式来重写父类的方法,要么(当父类不允许子类重写此方法时)就应该编译时报错。而.net 最初从c++中恰好继承了这个“可用完全无关的 Add 方法来重载父类Add方法”的特性,这本身是违反面向对象设计原则的,是容易让人产生误解的。
接下来,对于“索引符”,c#编译器要求必须是你声明的变量类型本身就定义有索引操作定义,而不管类型的父类/接口有没有可用的操作定义。因为这个[ ] 是一个语法糖,是c#的特性而不是 .net 的特性。(vb.net 中另外定义了其它语法形式的索引操作定义)
因此在这个索引操作符方面,其实c#也并没有按照面向对象的规范去定义,也是个特例。
当你写
public class Animals : CollectionBase也就是把所谓 Add 注释掉,第一段照样可以执行。
{
//public void Add(int newAnimal)
//{
// IList d = new Animals();
// d.Add(newAnimal);
//}
}
面向对象的分析和设计技术中,实际上应该避免这种用 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
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
#6
奇怪,我明明输入且提交的内容,csdn服务器刷新页面之后怎么直接丢掉了内容呢?!
不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。
如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL
不管关于“索引操作符不支持继承”的原因是c#编译器的缘故还是.net 类库中定义为间接引用父类(父接口)的缘故——实际上应该是后者的缘故,总之注意点都是一样的。这里你恰好遇到了两个及不符合面向对象分析设计规范的例子,一个是“子类使用相同签名的方法,已完全无关的内容,去重载父类的相同签名的方法”,第二个是“子类可以断然声明不支持父类/接口的方法”。这两个都是上个世纪末在OO 最终技术流行起来之前的风格,比较随意的 c++ 代码中才会常见。
如今只能注意避免踩上这些“坑”代码,如果你觉得这两个比较容易弄乱OOPL程序设计,我是同意的。如果遇到更好地编程语言或者开发平台,可以考虑因这些不符合OOAD的编程特性而扔掉c#和. net,选择更好地 OOPL
#7
它定义了几个父类接口方法不能直接使用,必须通过父类类型间接调用。我上面说的“现在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] 了
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了
#9
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了
我问一下 以专业开发人员为伍的代码是从哪里查到的 就是3楼的代码
#10
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
那他会执行吗?。。。
#11
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
那他会执行吗?。。。
会 你试验一下不就知道了嘛
#12
1. 直接下载.NET Framework源代码(
下载地址),然后用Visual Studio打开查看。
2. 在线查看,网址:http://referencesource.microsoft.com/ 。
VS 的联机帮助里也可看到
2. 在线查看,网址:http://referencesource.microsoft.com/ 。
VS 的联机帮助里也可看到
#13
public void Add(int newAnimal)
{
IList d = new Animals();
d.Add(newAnimal);
}
你确定你的第一段代码是对的 ?、、、、、、、
我确定 不信你可以上机实验一下
那他会执行吗?。。。
会 你试验一下不就知道了嘛
你是从哪里判断它执行了的?。。。就应为 你确实添加进去了数据吗?。。
你访问当的 压根就不是 Animals.Add 而是 IList.Add
如果上面的代码 真的是执行了的话 那就只能得到一个异常 *exception 栈溢出 很简单 那代码看上去就和死递归 没什么区别
#14
操作的对象不同,自然用法上也有所不同
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
操作的对象不同,自然用法上也有所不同
IList f = new Animals();
f 是 IList 类型的,IList 本身支持枚举,所以你可以 f[0]、f[1] 这样
Animals a = new Animals();
a 是 Animals 类型的,枚举是通过索引器定义的,你把索引器去掉,就不能 a[0]、a[1] 了
还是你说的此枚举非彼枚举?
#16
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] 这样访问吗?
如果 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
你又在钻牛角尖了吧?
如果 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
你又在钻牛角尖了吧?
如果 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
你又在钻牛角尖了吧?
如果 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
操作的对象不同,自然用法上也有所不同
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]; }
}
}