C#集合-

2021-07-12 09:07

阅读:587

标签:相关   size   exe   派生类   表达   ddr   直接   open   类成员   

      定义集合

  集合是可以包含其他类的实例的类。要定义集合,可以从CollectionBase中派生,或者自己实现接口,类如IEnumerable,ICollection和IList。一般需要为集合定义一个索引器,

以用Collection[index]来访问集合成员。(使用集合维护对象组)

 

       System.Collections命名空间中的几个接口提供了集合基本的功能:

  • IEnumerable 可以迭代集合中所有的项。
  • ICollection继承与IEnumberable,可以获取集合中项的个数,并且能把项复制到一个简单的数组类型中
  • IList继承于IEnuberable和ICollection提供了项的列表,允许访问这些项,并提供了一些与项列表相关的基本功能。
  • IDictionary继承于IEnuberable和ICollection,可通过键值访问项列表。

 

1.1.1 System.Collections.ArrayList实现了IList ICollection以及IEnumerable接口。

高级数组集合的使用:

ArrayList List=new ArrayList();
List.Add(new Animal("LALA"));
List.RemoveAt(0);
List.AddRange(...);

1.1.2 CollectionBase类的使用

CollectionBase类有接口IEnumerable、ICollection以及IList,但只提供了一些必要的实现代码,主要就是IList的Clear()和ReamoveAt()方法,以及ICollection的Count属性。

Add()和Reamove()方法是强类型化的方法,使用IList几口中用于访问项标准Add()方法。CollectionBase类可以使用foreach语法遍历成员

技术分享图片技术分享图片
public Class Animals: CollectionBase
{
   public void Add(Animal newAnimal)
  {
       List.Add(newAnimal)
  } 
    public void Remove(Animal oldAnimal)
    {
       List.Remove(oldAnimal)
    }
    public Animals()
   {

    }

}
View Code

1.1.3 索引符(indexer)

索引符是一个特殊类型的属性,可以把它添加到一个类中,以便提供类似数组的访问。

说白了,数组是有索引,所以可以快递定位数组中元素的位置。而索引符就是针对于其他类型的结构,切索引的类型是没有限定的.

    /// 
    /// 最简单的索引器
    /// 
    public class IDXer
    {
        private string[] name=new string[10];

        //索引器必须以this关键字定义,其实这个this就是类实例化之后的对象
        public string this[int index]
        {
            get 
            {
                return name[index];
            }
            set
            {
                name[index] = value;
            }
        }  
    }
        
    public class Program
    {
        static void Main(string[] args)
        {
            //最简单索引器的使用           
            IDXer indexer = new IDXer();
            //“=”号右边对索引器赋值,其实就是调用其set方法
            indexer[0] = "张三";
            indexer[1] = "李四";
            //输出索引器的值,其实就是调用其get方法
            Console.WriteLine(indexer[0]);
            Console.WriteLine(indexer[1]);
            Console.ReadKey();
        }
    }
//部分例子
public Class Animals:CollectionBase
{
  public void Add (Animal newAnimal)
  {
    List.Add(newAnimal);

  }
  public void Remove(Animal oldAnimal)
   {
     List.Remove(oldAnimal)

   }

  public Animal this[int animalIndex]
{
  get{return (Animal)List[animalIndex];}
set{List[animalIndex]=value;}
}
}
static void main(string[] args)
{
aniamals animalCollection=new Animals();
animalCollection.Add(new Cow("Danna"));
animalCollection.Add(new Chicken("Keve"));
foreach(Animal myanimal in animalCollection)
{
myanimal.Feed();

}

}

还有多重索引器和索引器重载.....

索引器和数组比较:

(1)索引器的索引值(Index)类型不受限制

(2)索引器允许重载

(3)索引器不是一个变量,索引器没有定义直接存储的地方,而数组有

索引器和属性的不同点

(1)属性以名称来标识,索引器以函数形式标识

(2)索引器可以被重载,属性不可以

(3)索引器不能声明为static,属性可以

1.1.4 键控集合和IDictionary

类似于IList接口通过数字索引访问项列表,IDictionary接口通过健值进行索引。同样,也有一个基类实现了IDictionary接口,DictionaryBase。

public class Animals:DictionaryBase
{
  public void Add(string newID,Animal newAnimal)

  {
    Dictionary.Add(newID,newAnimal);

   }

   public void Remove(string AnimalID)
   {
      Dictionary.Remove(animalID)

   }
    public Animals(){}
    public Animal this[string animalID]
    {
       get{return (Animal)Dictionary[animalID];}
       set{Dictionary[animalID]=value;}

    }

}

基于DictionaryBase的集合和基于CollectionBase的集合之间的另一个区别是foreach的工作方式有些区别。要从集合中提取对象,使用foreach和DictionaryBase的派生类可以提供DictionaryEntry结构

要得到对象本身,就必须使用这个结构value成员,亦可以使用结构的key成员得到相关的键。

foreach(DictionaryEntry myEntry in animalCollection)
{
WriteLine("new {0} object to custom collection, name={1}",myEntry.value.ToString(),(Animal)(myEntry.value).Name)

}

1.1.5迭代器

迭代器的定义是,他是一个代码块,按顺序提供了要在foreach块中的所有值。

如果要迭代一个类,就使用方法GetEnumeralble(),返回类型是IEnumerator;

如果要迭代一个类成员,就使用IEnumberable。

public static IEnumerable SimpleList()
{
yield return "string 1st";
yield return "string 2nd";
yield return "string 3rd";
}
static void Main(string[] args)
{
foreach(string item in simplelist())
{
Console.WriteLine(item);
}
Console.Read();
}

1.1.6深度复制

所谓深度复制和浅度复制,在值类型上感觉是没有区别的,都是复制一个值,而在引用类型上,浅度复制是复制对象的一个相同的引用,副本改变后则源也要改变。

但是深度复制则不同,其复制对象的内容(包括字段等)而引用不同,副本发生变化时,源则不变。

2.比较

2.1.1 封箱和拆箱

封箱是把值类型转换为System.Object类型,或者值类型转换为接口类型。拆箱是相反的过程。

封箱操作:

struct Mystruct
{
   public int val;
}



Mystruct valType=new Mystruct();
valType.val=1;
object refType=valType;

拆箱操作:

Mystruct valType1=(Mystruct)refType;

封箱是没有用户干涉的情况下进行的,而拆箱需要进行显示转换。(即封箱是隐式,拆箱式显示)

2.1.2 is运算符

is运算符用来检查对象是否为给定类型,或者是否能转换为给定类型

is运算符的语法如下:

is 

如果是一个类类型,也是该类型,或者继承了该类型,或者可以封箱到该类型中,则返回true。

2.1.3值比较

1.重载运算符,要在类中重载运算符,可以给类添加运算符成员,必须使用operater关键字,必须是static静态方法;

2.IComparable 和IComparer接口

  • IComparable在要比较的对象的类中实现,可以比较该对象和另一个对象
  • IComparer在一个单独的类中实现,可以比较任意两个对象

IComparable提供了CompareTo()这个方法接受一个对象和另一个对象比较

x.CompareTo(y);

IComparer提供了Compare(),这个方法接受两个对象比较,返回一个整形结果

Compare(x,y);

 

3.转换

(1)重载转换运算符

  在代码中,使用关键字implicit和explicit来指定转换

public class ConvClass1
    {
        public int val;
        public static implicit operator ConvClass2(ConvClass1 op1)
        {
            ConvClass2 returnVal = new ConvClass2();
            returnVal.val = op1.val;
            return returnVal;
        }

    }
    public class ConvClass2
    {
        public double val;
        public static explicit operator ConvClass1(ConvClass2 op1)
        {
            ConvClass1 returnVal = new ConvClass1();
            returnVal.val = (int)(op1.val);
            return returnVal;
        }
    }

(2) as运算符

使用下面的语法,把一种类型转换为指定的引用类型。

   as

  •  的类型是类型
  •   可以隐式转换为类型
  •    可以封箱到类型中

  如果不能从转换为,则表达式的结果为null。

C#集合-

标签:相关   size   exe   派生类   表达   ddr   直接   open   类成员   

原文地址:https://www.cnblogs.com/miko186/p/9609689.html


评论


亲,登录后才可以留言!