A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 飞、 中级黑马   /  2013-10-20 23:51  /  1793 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 飞、 于 2013-10-21 12:42 编辑

视频里似没有这么个东东呀?望详解

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

7 个回复

倒序浏览
在一个方法中,一个变量的值是可以作为参数,但其实这个变量的类型本身也可以作为参数。泛型允许我们在调用的时候再指定这个类型参数是什么。在.net中,泛型能够给我们带来的两个明显的好处是--类型安全和减少装箱、拆箱。

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
泛型概述
  使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。

  泛型最常见的用途是创建集合类。

  .NET Framework 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。应尽可能地使用这些类来代替普通的类,如 System.Collections 命名空间中的 ArrayList。

  您可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。

  可以对泛型类进行约束以访问特定数据类型的方法。

  关于泛型数据类型中使用的类型的信息可在运行时通过使用反射获取。

  优点
  泛型类和泛型方法同时具备可重用性、类型安全和效率,这是非泛型类和非泛型方法无法具备的。泛型通常用与集合以及作用于集合的方法一起使用。.NET Framework 2.0 版类库提供一个新的命名空间 System.Collections.Generic,其中包含几个新的基于泛型的集合类。建议面向 .NET Framework 2.0 及更高版本的所有应用程序都使用新的泛型集合类,而不要使用旧的非泛型集合类如 ArrayList。
  何时使用泛型集合

  通常情况下,建议您使用泛型集合,因为这样可以获得类型安全的直接优点而不需要从基集合类型派生并实现类型特定的成员。此外,如果集合元素为值类型,泛型集合类型的性能通常优于对应的非泛型集合类型(并优于从非泛型基集合类型派生的类型),因为使用泛型时不必对元素进行装箱。

  下面的泛型类型对应于现有的集合类型:

  List<(Of <(T>)>) 是对应于 ArrayList 的泛型类。

  Dictionary<(Of <(TKey, TValue>)>) 是对应于 Hashtable 的泛型类。

  Collection<(Of <(T>)>) 是对应于 CollectionBase 的泛型类。Collection<(Of <(T>)>) 可以用作基类,但与 CollectionBase 不同的是它不是抽象的。这样使用起来要方便得多。

  ReadOnlyCollection<(Of <(T>)>) 是对应于 ReadOnlyCollectionBase 的泛型类。ReadOnlyCollection<(Of <(T>)>) 不是抽象的,它具有一个构造函数,该构造函数使其易于将现有的 List<(Of <(T>)>) 公开为只读集合。

  Queue<(Of <(T>)>)、Stack<(Of <(T>)>) 和 SortedList<(Of <(TKey, TValue>)>) 泛型类分别对应于与其同名的非泛型类。

  其他类型
  有几种泛型集合类型没有对应的非泛型类型:

  LinkedList<(Of <(T>)>) 是一个通用链接列表,它提供运算复杂度为 O(1) 的插入和移除操作。

  SortedDictionary<(Of <(TKey, TValue>)>) 是一个排序的字典,其插入和检索操作的运算复杂度为 O(log n),这使得它成为 SortedList<(Of <(TKey, TValue>)>) 的十分有用的替代类型。

  KeyedCollection<(Of <(TKey, TItem>)>) 是介于列表和字典之间的混合类型,它提供了一种存储包含自己键的对象的方法。

  LINQ to Objects
  LINQ to Objects 功能允许使用 LINQ 查询访问内存中的对象,但条件是该对象类型要实现 IEnumerable 或 IEnumerable<(Of <(T>)>)。LINQ 查询提供了一种通用的数据访问模式;与标准 foreach 循环相比,它通常更加简洁,可读性更高;这种查询可提供筛选、排序和分组功能。LINQ 查询还可提高性能。有关更多信息,请参见 LINQ to Objects。

  其他功能
  一些泛型类型具有非泛型集合类型中没有的功能。例如,List<(Of <(T>)>) 类(对应于非泛型 ArrayList 类)具有许多接受泛型委托(如允许指定搜索列表的方法的 Predicate<(Of <(T>)>) 委托、表示操作每个列表元素的 Action<(Of <(T>)>) 委托和允许定义类型之间转换的 Converter<(Of <(TInput, TOutput>)>) 委托)的方法。

  List<(Of <(T>)>) 类允许指定您自己的用于排序和搜索列表的 IComparer<(Of <(T>)>) 泛型接口实现。SortedDictionary<(Of <(TKey, TValue>)>) 和 SortedList<(Of <(TKey, TValue>)>) 类也具有此功能,此外还允许在创建集合时指定比较器。类似地,Dictionary<(Of <(TKey, TValue>)>) 和 KeyedCollection<(Of <(TKey, TItem>)>) 类允许您指定自己的相等比较器。

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
泛型把类或方法的类型的确定推迟到实例化该类或方法的时候 ,也就是说刚开始声明是不指定类型,等到要使用(实例化)时再指定类型

泛型可以用于  类、方法、委托、事件等

下面先写一个简单的泛型

public class GenericClass<T>

{

          void SomeMethod(  T   t  )

          {

                   //do something

          }

}

其使用方法如下:

实例化一个类

GenericClass<int> gci=new GenericClass<int>();方法SomeMethod就具有整数类型的参数了

下面写一个例子

using System;
using System.Collections.Generic;
using System.Text;

namespace example
{
    class GenericClass<T>
    {
        public void PrintType(T t)
        {
            Console.WriteLine("Value:{0}    Type:{1}",t,t.GetType());
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            int i = 0;
            GenericClass<int> gci = new GenericClass<int>();
            gci.PrintType(i);

            string s = "hello";
            GenericClass<string> gcs = new GenericClass<string>();
            gcs.PrintType(s);
            Console.ReadLine();
        }
    }
}



泛型方法可以出现在泛型或非泛型类型上。需要注意的是,并不是只要方法属于泛型类型,或者甚至是方法的形参的类型是封闭类型的泛型参数,就可以说方法是泛型方法。只有当方法具有它自己的类型参数列表时,才能称其为泛型方法。在下面的代码中,只有方法 G 是泛型方法。
class A
{
    T G<T>(T arg) {...}
}
class Generic<T>
{
    T M(T arg) {...}
}



泛型的Where

  泛型的Where能够对类型参数作出限定。有以下几种方式。

  ·where T : struct 限制类型参数T必须继承自System.ValueType。
 
  ·where T : class 限制类型参数T必须是引用类型,也就是不能继承自System.ValueType。

  ·where T : new() 限制类型参数T必须有一个缺省的构造函数

  ·where T : NameOfClass 限制类型参数T必须继承自某个类或实现某个接口。

  以上这些限定可以组合使用,比如: public class Point where T : class, IComparable, new()



例如:
    class Person<T> where T:class
    {
        
    }

    class Program
    {
        static void Main(string[] args)
        {
           
            Person<int> bb = new Person<int>(); //報錯,
错误 1 类型“int”必须是引用类型才能用作泛型类型或方法“ConsoleApplication1.Person<T>”中的参数“T”

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
C#2.0提出的泛型就是避免强制类型转换,减少装箱拆箱提高性能,减少错误。

System.Collections.Generic命名空间提供许多集合类和接口的泛型版本。

定义:
public class GenericList<T>
{
    public void Add(T input)//T制定成类型参数
    public T Add()//T制定成返回值
}
<T>的T是类型参数,起占位符的作用,编译时被真正类型取代。

使用泛型:
GenericList<int> list1 = new GenericList<int>();
GenericList<string> list2 = new GenericList<string>();
GenericList<类名> list3 = new GenericList<类名>();
GenericList<类名<int>> list4= new GenericList<类名<int>>();
以list1为例编译器生成以下的方法:
    public void Add(int input)
    public int Add()

有多个类型参数的泛型类:
public class 类名<T,U>

泛型约束:
确保泛型类使用的参数是提供特定方法的类型。
public class GenericList<T> where T : IEmployee
假如IEmployee接口包含A方法,编译器会验证用于替换T的类型一定要实现IEmployee接口。

泛型方法:允许采取定义泛型类时采用的方式

//定义泛型方法
static void Swap<T>(ref T lhs, ref T rhs)

{ T temp; temp = lhs; lhs = rhs; rhs = temp; }
/使用泛型方法

public static void TestSwap(){    int a=1,b=3;
Swap<int>(ref a,ref b);


string s1="Hello",s2="world";
Swap<string>(ref s1,ref s2);}

有泛型类,泛型接口,泛型方法,泛型委托

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
即通过参数化类型来实现在同一份代码上操作多种数据类型。
泛型是在C#2.0引入的。泛型(Genericity)的字面意思是指具有在多种数据类型上皆可操作的含意,与模板有些相似。泛型引入了类型参数化的概念,旨在实现定义的泛型类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险。为了使用这些强有力的数据结构,你所要做的仅是提供数据类型。
C#泛型的几个特点:
(1)如果实例化泛型类型的参数相同,那么JIT编译器会重复使用该类型。
(2)C#的泛型类型可以应用于强大的反射技术。
(3)C#的性能高,我们知道ArrayList添加元素时都是object类型,如果添加一个值类型,就需要把它转换为引用类型,当取出这个元素的时候又要将其转换为值类型,这就需要装箱和拆箱的操作,性能降低。而泛型无需类型的转换操作。
(4)C#除可单独声明泛型类型(包括类与结构)外,也可在基类中包含泛型类型的声明。但基类如果是泛型类,它的类型参数要么已实例化,要么来源子类(同样是泛型类型)声明的类型参数。

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
泛型具备类型安全(不用装箱、拆箱),和效率。下面的代码你要是能弄明白,相信你就会大概明白泛型是什么,怎么来的。

//T是类型参数
    public class GenericList<T>
    {
        //嵌套类,表示节点类
        class Node
        {
            Node next;//表示下一个节点
            T data;//表示当前节点存储的数据(T类型)
            public Node Next
            {
                get { return next; }
                set { next = value; }
            }
            public T Data
            {
                get { return data; }
                set { data = value; }
            }
            //构造函数
            public Node(T t)
            {
                next = null;
                data = t;
            }
        }

        Node head;//GenericList<T>类的字段,表示头节点

        public GenericList()
        {
            head = null;
        }
        //为GenericList添加节点的方法,t是数据
        public void AddHead(T t)
        {
            Node n = new Node(t);//首先把数据t保存在节点类型中
            n.Next = head;//当前存了数据的节点的下一个节点的值变为当前list对象的head
            head = n;//把n存为头节点
            //即向前添加的,把一个节点插入到list中的头部,后面的数据依次往后排
        }
        public IEnumerator<T> GetEnumerator()//IEnumerator<T>为泛型集合提供迭代功能的接口
        {
            Node current = head;//当前节点
            while (current!=null)//当前节点不为空,则迭代返回其数据,并且跳到下一个节点
            {
                yield return current.Data;
                current = current.Next;
            }
        }
    }
    public class Program
    {
        static void Main(string[] args)
        {
            GenericList<int> list = new GenericList<int>();
            for (int i = 0; i < 10; i++)
            {
                list.AddHead(i);
            }
            foreach (int data in list)//可以用foreach是因为GenericList实现了IEnumerator<T>
            {
                Console.Write(data+"  ");
            }
            Console.ReadKey();
        }
    }

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
泛型
所谓泛型,就是创建使用通用(而不是特定)类型的类或方法。

泛型主要的改进方面:
     1.二进制代码的重用。泛型类可以用户任何类型
     2.性能:减少了装箱 拆箱过程中的性能损耗
     3.易于阅读
     4.类型安全:如传统的ArrayList可以把任意对象作为参数放在其Add方法中。编译器不考虑这些,所以集合中提取对象
时,除非强制类型转换失败,否则我们不知道出了问题。而泛型有内置的类型安全,如果进出泛型集合类时违反了类型检查过则,编译器就会报告错误。

所有泛型集合都在System.Collection.Generic中。

评分

参与人数 1技术分 +1 收起 理由
haxyek + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马