C#泛型集合类System.Collections.Generic

目录
  • 一、定义泛型类
  • 二、从泛型类继承
  • 三、定义泛型运算符
  • 四、定义泛型结构
  • 五、定义泛型接口
  • 六、定义泛型方法
    • 1、普通类
    • 2、泛型类
  • 七、定义泛型委托
    • 1、通过泛型委托,委托的参数可以在以后定义。
    • 2、常用内置委托:
    • 3、实例:
  • 八、定义泛型事件
  • 九、可空类型System.Nullable<T>
    • 1、声明和赋值
    • 2、判断为空
    • 3、转换
  • 十、ArraySegement<T> 数组片段

一、定义泛型类

void Main()
{
    //实例化泛型类时,才指定具体的类型
    MyGenericClass<int> MyGeneri = new MyGenericClass<int>(5);
    Console.WriteLine(MyGeneri.InnerT1Object * 2);
}

public class MyGenericClass<T>//<T1,T2,T3>表示多个类型参数
{
    private T innerT1Object;
    public string LastName;
public MyGenericClass(T item)//构造函数
    {
        this.innerT1Object = item;
    }
public T InnerT1Object//泛型属性
    {
        get { return innerT1Object; }
    }
}

注意:

1、不能假定T提供了什么类型。

eg:innerT1Object=new T(),因为T可能根本无公共默认构造函数。除非 class MyGenericClass<T> where T:new()

public class MyGenericClass<T> where T : new()
{
    private T innerT1Object = new T();
}

2、可以把T看作继承System.Object的类型:typeof(T),T.ToString()

3、在没有指定约束类型参数的情况下,比较泛型类型值和null,只能使用==或!=。

不能对两个类型值变量进行比较。

public bool Compare(T op1, T op2)
{
    if (op1 != null && op2 == null)//正确。如果T为值类型,op1!=null始终成立。
    {
        //…
    }
    if (op1 == op2)//错误,因为这就假定了T支持==运算符
    {
        //…
    }
}

4、default关键字用于为T赋默认值,而无需考虑其实值类型还是引用类型。

public class MyGenericClass<T>
{
    private T innerT1Object = default(T);
}

5、where 关键字用于约束T的类型。

class MyGenericClass<T> where T:Animal

可用的约束有:

  • struct :值类型
  • class:引用类型
  • <baseclass>:此列或者此类的派生类
  • <interface>:此接口或者实现此接口
  • new():必须具有无参数的公共构造函数。必须为类型的最后得约束。
  • 一个类型参数可有多个约束:class Myclass<T> where T: constait1,constrait2
  • 各类型参数不同的约束:class Myclass<T1,T2> where T1: constait1,T2:constrait2
  • 约束放于继承符之后:class Myclass<T1>:MyBaseCalss,IMyInterface where T: constait
  • 一个类型参数用作另一个类型参数的约束,表示T2与T1的类型相同,或T2继承于T1(裸类型约束)class Myclass<T1,T2> where T2: T1

6、泛型类的静态成员只能在类的一个实例中共享:

void Main()
{
    StaticDemo<string>.x=4;
    StaticDemo<int>.x=5;
}

public class StaticDemo<T>
{
    public  static int x;
}

二、从泛型类继承

1、泛型类至少与基类有相同的约束,或为基类的子集

public class Farm<T> where T : Animal
{
    //...
}

public class SuperFarm<T> : Farm<T> where T : SuperCow //SuperCow为Animal的子集
{
    //...
}

2、类继承泛型,必须提供所有的类型信息

public class Cards : List<Card> //派生非泛型
{ }

三、定义泛型运算符

public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2)
{ }

四、定义泛型结构

public struct MyStruct<T1, T2>
{
    public T1 item1;
    public T2 item2;
}

五、定义泛型接口

interface myInterface<T> where T : Animal
{
    bool Brea(T animal1, T animal2);
    T oldest { get; }
}

实例:

public interface IComparable<T>
{
    int CompareTo(T other);
}

public class Person : IComparable<Person>
{
    public int CompareTo(Person other)
    {
        return this.name.CompareTO(other.name);
    }
}

六、定义泛型方法

1、普通类

public class Defaulter
{
    public T GetDefault<T>()
    {
        return default(T);
    }
}

2、泛型类

public class Defaulter<T1>
{
    public T2 GetDefault<T2>() where T2 : T1 //泛型方法的参数最好不要与其所在的泛型类的类型参数相同
    {
        return default(T2);
    }

    public void Process()
    {
    }
    public void Process<T>(T1 op1)//重载方法1
    {
    }

    public void Process<T, U>(T1 op1)//重载方法2
    {
    }
}

七、定义泛型委托

1、通过泛型委托,委托的参数可以在以后定义。

public delegate T1 MyDelegate<T1, T2>(T2 op1, T2 op2) where T1 : T2;

2、常用内置委托:

(1)、Action<T>: 泛型委托。无返回值。 委托的方法可以有1-16个输入参数。Action:无参数无返回值委托。

Action action1 = () => Console.Write("a");
action1();

Action<string> action2 = (p) => Console.Write(p);
action2("b");

利用Action实现线程和界面交互:

private void button1_Click(object sender, EventArgs e)
{
    WaitCallback waitCallBack = new WaitCallback(this.AlternationUsingAction);
    ThreadPool.QueueUserWorkItem(waitCallBack, "Action的使用");
}

private void AlternationUsingAction(object text)
{
    this.Invoke((Action)( () =>
      {
          button1.Text = text.ToString();
      } ));
}

(2)、Func<T>:必须具有返回值。委托的方法可以有0-16个参数输入参数,加一个输出参数。

Func<int, int, string > Func = (a, b) => (a + b).ToString();
Console.Write(Func(1, 2));

(3)、Predicate<T>:就是只接受一个传入参数,返回值为bool类型。

用于搜索方法

public delegate bool Predicate<T>(T obj);//判断条件函数
public T Find(Predicate<T> matach);

举例:

Predicate<string[]> predicate = x =>
                   {
                       var result = from p in x
                                    where p.Contains("s")
                                    select p;
                       return result.ToList().Count > 0;

                   };
string[] _value = { "charlies", "nancy", "alex", "jimmy", "selina" };
Console.WriteLine(predicate(_value) ? "包含." : "不包含");

(4)、Comparision<T>(T obj1,T obj2):比较函数,用于搜索方法。

public delegate int Comparision<T>(T obj1,T obj2)//
public void Sort(Comparision<T> comprison)

(5)、EventHandler<TEventArgs>:泛型事件处理函数。

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;

3、实例:

public delegate TSummary Action<TInput, TSummary>(TInput t, TSummary u);//定义泛型委托
public static TSummary Accumulate<TInput, TSummary>(IEnumerable <TInput> cols, Action<TInput, TSummary> action)
//将委托实例action传给方法参数。
{
    TSummary sum = default(TSummary);
    foreach (TInput input in cols)
    {
        sum = action(input, sum);//执行委托方法
    }
    return sum;
}

void Main()
{
    decimal amount = Accumulate<int, decimal>(new List<int> { 1, 2 }, (a, b) => a + b);//(a, b) => a + b为委托实例
    Console.Write(amount);
}

八、定义泛型事件

事件与委托就像一对孪生兄弟。既然有泛型委托,那么也应该有泛型事件。因为在以前,事件处理函数的发送方参数的类型总是Object。因此事件处理函数没有办法根据不同的发送者身份或者类型对事件进行不同的处理。现在如果使用泛型事件就可以使用强类型的发送方,不再需要强制转换成Object或反向强制转换。而且也可以根据发送方类型的不同对消息进行不同的处理。

例子中演示了发送方是强类型的情况,在这个例子中使用泛型类Publisher<T>来表示消息的发布者,用类Receiver来表示消息的订阅者。

//定义了一个泛型委托,该委托指定了发送者的具体类型
public delegate void MyEventHandler<T>(Publisher<T> Sender);

void Main()
{
    //事件发布者
    Publisher<int> publisherI = new Publisher<int>();
    Publisher<double> publisherD = new Publisher<double>();

    //事件订阅者
    Receiver receiver = new Receiver();

    //开始绑定事件
    publisherI.Click += receiver.OnClick;
    publisherD.Click += receiver.OnClick;

    //引发事件
    publisherI.SendMessage();
    publisherD.SendMessage();
}

//消息发布者类Publisher<T>的代码
public class Publisher<T>
{
    //定义了一个泛型事件,该事件的发布者的类型是强类型
    public event MyEventHandler<T> Click;

    //发送事件函数
    public void SendMessage()
    {
        Click(this);
    }
}

//消息订阅者类Receiver的代码
class Receiver
{
    //事件处理函数,该函数具有强类型的参数表示发送者
    public void OnClick(Publisher<int> sender)
    {
        Console.WriteLine("该事件已经写入日志文件");
    }

    //事件处理函数
    public void OnClick(Publisher<double> sender)
    {
        Console.WriteLine("该事件已经发送到主管信箱");
    }
}

九、可空类型System.Nullable<T>

1、声明和赋值

Nullable<int> x = 4;//可写成int? x = 4
x = null;//可为可空类型赋值null.

2、判断为空

int y;
if (x.HasValue)//或者x!=null
{
    y = x = value;
}
else
{
    y = x ?? 0;//或者    x.GetValueOrDefault(); x=null则或者其默认值。
}

3、转换

int? op1=5;
int? result=op1 *2;

int? op2=5;
int result1=op2 *2;//如果op2为null,强制转换int?到int产生异常

十、ArraySegement<T> 数组片段

int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };
ArraySegment<int> segment = new ArraySegment<int>(arr, 2, 3);
for (int i = segment.Offset; i < segment.Offset + segment.Count; i++)
{
    Console.WriteLine(segment.Array[i]);
}

到此这篇关于C#泛型集合类System.Collections.Generic的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C# 泛型集合的自定义类型排序的实现

    一.泛型集合List<T>排序 经sort方法之后,采用了升序的方式进行排列的. List<int> list = new List<int>() { 2, 4, 1, 3, 5, -2, 0, 10 }; Console.Write("排序前..."); foreach (var item in list) { Console.Write(item + "\t"); } list.Sort(); Console.WriteLin

  • C# 泛型的简单理解(安全、集合、方法、约束、继承)分享

    前言 泛型允许你在编译时实现类型安全.它们允许你创建一个数据结构而不限于一特定的数据类型.然而,当使用该数据结构时,编译器保证它使用的类型与类型安全是相一致的.泛型提供了类型安全,但是没有造成任何性能损失和代码臃肿.在这方面,它们很类似于C++中的模板,不过它们在实现上是很不同的. 使用泛型集合 .NET 2.0的System.Collections.Generics 命名空间包含了泛型集合定义.各种不同的集合/容器类都被"参数化"了.为使用它们,只需简单地指定参数化的类型即可. 复制

  • C#中利用LINQ to XML与反射把任意类型的泛型集合转换成XML格式字符串的方法

    在工作中,如果需要跟XML打交道,难免会遇到需要把一个类型集合转换成XML格式的情况.之前的方法比较笨拙,需要给不同的类型,各自写一个转换的函数.但是后来接触反射后,就知道可以利用反射去读取一个类型的所有成员,也就意味着可以替不同的类型,创建更通用的方法.这个例子是这样做的:利用反射,读取一个类型的所有属性,然后再把属性转换成XML元素的属性或者子元素.下面注释比较完整,就话不多说了,有需要看代码吧! using System; using System.Collections.Generic;

  • C#泛型集合Dictionary<K,V>的使用方法

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成 2).任何键都必须是唯一的 3).键不能为空引用null(VB中的Nothing),若值为引用类型,则可以为空值 4).Key和Value可以是任何类型(string,int,custom class 等) 3.创建及初始化 复制代码 代码如下:

  • C#控制台基础 List泛型集合与对应的数组相互转换实现代码

    核心代码: using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication10 { class Program { static void Main(string[] args) { List<int> list = new List&l

  • C#值类型、引用类型、泛型、集合、调用函数的表达式树实践

    目录 一,定义变量 二,访问变量/类型的属性字段和方法 1. 访问属性 调用静态类型属性 调用实例属性/字段 2. 调用函数 调用静态类型的函数 调用实例的函数 三,实例化引用类型 new 给属性赋值 创建引用类型 示例 四,实例化泛型类型于调用 五,定义集合变量.初始化.添加元素 一,定义变量 C# 表达式树中,定义一个变量,使用 ParameterExpression. 创建变量结点的方法有两种, Expression.Parameter() Expression.Variable() //

  • C#中Dictionary泛型集合7种常见的用法

    要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib)  Dictionary的描述 1.从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成 2.任何键都必须是唯一的 3.键不能为空引用null(VB中的Nothing),若值为引用类型,则可以为空值 4.Key和Value可以是任何类型(string,int,custom class 等) Dictionary常用用法:以

  • C#中把任意类型的泛型集合转换成SQLXML数据格式的实例

    话不多说,跟着小编一起来看下吧 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data.SqlTypes; using System.Data; using System.Reflection; using System.IO; using System.Xml; namespace CollectionToXml { class Program

  • C#泛型集合类System.Collections.Generic

    目录 一.定义泛型类 二.从泛型类继承 三.定义泛型运算符 四.定义泛型结构 五.定义泛型接口 六.定义泛型方法 1.普通类 2.泛型类 七.定义泛型委托 1.通过泛型委托,委托的参数可以在以后定义. 2.常用内置委托: 3.实例: 八.定义泛型事件 九.可空类型System.Nullable<T> 1.声明和赋值 2.判断为空 3.转换 十.ArraySegement<T> 数组片段 一.定义泛型类 void Main() { //实例化泛型类时,才指定具体的类型 MyGener

  • C# 泛型集合类List<T>使用总结

    目录 为什么选择使用List,而不是使用Array,或者ArryList 去重.交集.并集.差集操作 重写Equals() 和 GetHashCode() 简单使用 C#中List可谓是使用最广泛的一种数据类型了,使用他来规范数据时,往往会涉及到对数据的处理操作,相关处理数据方法也非常丰富,本文将简单介绍为何使用它,以及部分处理方法的灵活使用. 为什么选择使用List,而不是使用Array,或者ArryList 首先要说下数组的局限性 (1) 数组中元素是固定的:类型和数量都必须确定!一旦定义,

  • C#关于System.Collections空间详解

    C#的System.Collections命名空间包含可使用的集合类和相关的接口,提供了集合的基本功能.包括了.NET下的非泛型集合类以及非泛型接口等,现详述如下: 该命名空间下的.NET非泛型集合类如下所示: - System.Collections.ArrayList:数组集合类,使用大小可按动态增加的数组实现Ilist接口. - System.Collections.BitArray:布尔集合类,管理位值的压缩数组,该值为布尔值. - System.Collections.Queue:队列

  • C# ListView 点击表头对数据进行排序功能的实现代码

    添加表头单击事件 private void listView1_ColumnClick(object sender, ColumnClickEventArgs e) { if (listView1.Columns[e.Column].Tag == null) { listView1.Columns[e.Column].Tag = true; } bool tabK = (bool)listView1.Columns[e.Column].Tag; if (tabK) { listView1.Col

  • C# Dictionary和SortedDictionary的简介

    1.SortedDictionary 泛型类 SortedDictionary 泛型类是检索运算复杂度为 O(log n) 的二叉搜索树,其中 n 是字典中的元素数.就这一点而言,它与 SortedList 泛型类相似.这两个类具有相似的对象模型,并且都具有 O(log n) 的检索运算复杂度.这两个类的区别在于内存的使用以及插入和移除元素的速度: SortedList 使用的内存比 SortedDictionary 少. SortedDictionary 可对未排序的数据执行更快的插入和移除操

  • C#字典Dictionary的用法说明(注重性能版)

    前言 以键值对Dictionary<[key], [value]>形式存值,和哈希表很像也是一种无序的结构. 要使用Dictionary,需要先导入C#泛型命名空间System.Collections.Generic Dictionary需要注意的特性 1.任何键都必须是唯一的 --> 不能添加相同key的键值对,不然就报错: 如果要修改已有key对应的value,可以这样做: 2.Unity5.4以下的版本,最好不要用foreach来遍历字典: 法一:foreach遍历字典,会生成GC

  • 实例讲解C# 泛型(Generic)

    泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候.换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法. 您可以通过数据类型的替代参数编写类或方法的规范.当编译器遇到类的构造函数或方法的函数调用时,它会生成代码来处理指定的数据类型.下面这个简单的实例将有助于您理解这个概念: using System; using System.Collections.Generic; namespace GenericApplication {

  • 编写高质量代码改善C#程序——使用泛型集合代替非泛型集合(建议20)

    软件开发过程中,不可避免会用到集合,C#中的集合表现为数组和若干集合类.不管是数组还是集合类,它们都有各自的优缺点.如何使用好集合是我们在开发过程中必须掌握的技巧.不要小看这些技巧,一旦在开发中使用了错误的集合或针对集合的方法,应用程序将会背离你的预想而运行. 建议20:使用泛型集合代替非泛型集合 在建议1中我们知道,如果要让代码高效运行,应该尽量避免装箱和拆箱,以及尽量减少转型.很遗憾,在微软提供给我们的第一代集合类型中没有做到这一点,下面我们看ArrayList这个类的使用情况: Array

  • C#泛型Dictionary的用法实例详解

    本文以实例形式讲述了C#中的泛型Dictionary的用法.具有很好的实用价值.分享给大家供大家参考.具体如下: 泛型最常见的用途是泛型集合,命名空间System.Collections.Generic 中包含了一些基于泛型的集合类,使用泛型集合类可以提供更高的类型安全性,还有更高的性能,避免了非泛型集合的重复的装箱和拆箱. 很多非泛型集合类都有对应的泛型集合类,下面是常用的非泛型集合类以及对应的泛型集合类: 非泛型集合类 泛型集合类 ArrayList List<T> HashTable D

随机推荐