using System.Collections.Generic;
using System.Text;
namespace ICollectionTest
{
class Fruit
{
public string Name;
public int Price;
}
class Box : ICollection<Fruit>
{
public List<Fruit> _fruit = new List<Fruit>();
public int Count
{
get { return _fruit.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public void Add(Fruit item)
{
_fruit.Add(item);
}
public void Clear()
{
_fruit.Clear();
}
public bool Contains(Fruit item)
{
return _fruit.Contains(item);
}
public void CopyTo(Fruit[] array, int arrayIndex)
{
_fruit.CopyTo(array, arrayIndex);
}
IEnumerator<Fruit> IEnumerable<Fruit>.GetEnumerator()
{
foreach (var f in _fruit) yield return f;
}
public IEnumerator<Fruit> GetEnumerator()
{
foreach (var f in _fruit) yield return f;
}
public bool Remove(Fruit item)
{
return _fruit.Remove(item);
}
//void ICollection<Fruit>.Add(Fruit item)
//{
// throw new NotImplementedException();
//}
//void ICollection<Fruit>.Clear()
//{
// throw new NotImplementedException();
//}
//bool ICollection<Fruit>.Contains(Fruit item)
//{
// throw new NotImplementedException();
//}
//void ICollection<Fruit>.CopyTo(Fruit[] array, int arrayIndex)
//{
// throw new NotImplementedException();
//}
//int ICollection<Fruit>.Count
//{
// get { throw new NotImplementedException(); }
//}
//bool ICollection<Fruit>.IsReadOnly
//{
// get { throw new NotImplementedException(); }
//}
//bool ICollection<Fruit>.Remove(Fruit item)
//{
// throw new NotImplementedException();
//}
//IEnumerator<Fruit> IEnumerable<Fruit>.GetEnumerator()
//{
// throw new NotImplementedException();
//}
//System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
//{
// throw new NotImplementedException();
//}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
foreach (var f in _fruit) yield return f;
}
}
class Program
{
static void Main(string[] args)
{
Box box = new Box();
box.Add(new Fruit { Name = "apple", Price = 14 });
box.Add(new Fruit { Name = "orange", Price = 18 });
box.Add(new Fruit { Name = "grape", Price = 30 });
box.Add(new Fruit { Name = "banana", Price = 20});
foreach (var b in box) Console.WriteLine("{0},{1}", b.Name, b.Price);
Console.WriteLine("元素个数:{0}", box.Count);
Fruit fruit = new Fruit { Name="meloon",Price=19};
box.Add(fruit);
Console.WriteLine(box.Contains(fruit));
Console.WriteLine("元素个数:{0}", box.Count);
Console.WriteLine(box.Remove(fruit));
Console.WriteLine("元素个数:{0}", box.Count);
Console.ReadKey();
Console.WriteLine(box.Remove(fruit));
Console.WriteLine("元素个数:{0}", box.Count);
Console.ReadKey();
}
}
}
////apple,14
////orange,18
////grape,30
////banana,20
////元素个数:4
////True
////元素个数:5
////True
////元素个数:4
////False
////元素个数:4
////请按任意键继续. . .
C# 常用接口学习 ICollection<T>
作者:乌龙哈里
时间:2015-11-01
平台:Window7 64bit,Visual Studio Community 2015
参考:
章节:
- 接口 ICollection<T> 实现
正文:
我们先来看看 ICollection<T>的源代码:
public interface ICollection<T> : IEnumerable<T> { int Count { get; } bool IsReadOnly { get; } void Add(T item); void Clear(); bool Contains(T item); void CopyTo(T[] array, int arrayIndex); bool Remove(T item); }
看着这些接口方法,觉得 ICollection<T> 接口比 IEnumerable<T> 多了好多东西,如果我们只是要简单的 foreach,只要实现 IEnumerable<T>接口就够了。但如果我们还要了解元素的数量、增加删除元素等,那只好实现ICollection<T> 接口了。
class Fruit { public string Name; public int Price; }
假设我们有个 Box 类是上面这个 Fruit 类的集合,首先我们要在 Box 类中放一个 List<T> 容器来放置元素,然后再在 Box 类上实现 ICollection<T> 接口。
class Box : ICollection<Fruit> { public List<Fruit> _fruit = new List<Fruit>(); public int Count { get {return _fruit.Count();} } public bool IsReadOnly { get {return false;} } public void Add(Fruit item) { _fruit.Add(item); } public void Clear() { _fruit.Clear(); } public bool Contains(Fruit item) { return _fruit.Contains(item); } public void CopyTo(Fruit[] array, int arrayIndex) { _fruit.CopyTo(array,arrayIndex); } IEnumerator IEnumerable.GetEnumerator() { foreach(var f in _fruit) yield return f; } public IEnumerator<Fruit> GetEnumerator() { foreach (var f in _fruit) yield return f; } public bool Remove(Fruit item) { return _fruit.Remove(item); } }
一大坨方法要让我们填空。其实我感觉都是在 List<T> 上套了一个包装,实质上的实现都是要靠 List<T>。 (这里真的要感谢伟大的 Visual Studio IDE 帮我们罗列了那么多接口的填空,要不然真的会遗漏的。)。把空填完后,把所有方法都加个 public ,一个新鲜热辣的符合 ICollection<T> 约定的类就出炉了。下来我们调用:
static void Main(string[] args) { Box box = new Box(); box.Add(new Fruit { Name = "apple", Price = 14 }); box.Add(new Fruit { Name = "orange", Price = 18 }); box.Add(new Fruit { Name = "grape", Price = 30 }); box.Add(new Fruit { Name = "banana", Price = 20}); foreach (var b in box) Console.WriteLine($"{b.Name} {b.Price }"); Console.WriteLine($"元素个数:{box.Count}"); Fruit fruit = new Fruit { Name="meloon",Price=19}; box.Add(fruit); Console.WriteLine(box.Contains(fruit)); Console.WriteLine($"元素个数:{box.Count}"); Console.WriteLine(box.Remove(fruit)); Console.WriteLine($"元素个数:{box.Count}"); Console.ReadKey(); } //输出显示: apple 14 orange 18 grape 30 banana 20 元素个数:4 True 元素个数:5 True 元素个数:4
那个参考三关于几个接口的用处说得很详细,要牢牢记住。
不过我认为 C# 还是设计得太高端了,我们自己实现这些感觉都是在系统给的类型上包裹一下,不过话说回来也是很方便和放心。等以后功力深厚了再去研究系统给的那几个类型。
本文结束。再次感谢现阶段宇宙最完美的C#语言的IDE Visual Studio,该我们这些初学者带来许多便利。