C#中的泛型-1

在软件这个行业,做的越久,往往会觉得很多技术问题最终会偏向数据结构和算法。

记得曾经大学的一堂课上,老师讲了一个关于冒泡排序的算法,下面是课本上的标准实现。


 1 public class Sort
2 {
3 public void sortArray(int[] arry)
4 {
5 int length = arry.Length;
6 for (int i = 0; i <= length - 2; i++)
7 {
8 for (int j = length - 1; j >= 1; j--)
9 {
10 if (arry[j]<arry[j - 1])
11 {
12 int temp = arry[j];
13 arry[j] = arry[j - 1];
14 arry[j - 1] = temp;
15 }
16 }
17 }
18 }
19 }

当然,就排序本身不是我们这里要讨论的问题。上面的代码实现了一个功能:将一组数组元素按照从大到小的顺序排列。
   
进行简单的测试


 1 static void Main(string[] args)
2 {
3 Sort sor = new Sort();
4 //创建一个int数组
5 int[] array = { 8,1,4,7,3};
6 //排序
7 sor.sortArray(array);
8 //打印排序结果
9 foreach (int i in array)
10 {
11 Console.WriteLine("{0} : ",i);
12 }
13 Console.ReadLine();
14 }

得到的结果是:
1  3  4  7  8

发现结果ok,心想这就是完美的了。但是不久之后,又需要对一个byte数组进行排序,而这个程序只接受int型参数,尽管byte的数据范围是int的子集,但是强类型的C#语言不允许我们在一个接受int的地方传入byte,不过没关系,灵机一动,把上面代码复制一边,参数改为byte[]不久好了。


 1 public class Sort
2 {
3 public void sortArray(byte[] arry)
4 {
5 int length = arry.Length;
6 for (int i = 0; i <= length - 2; i++)
7 {
8 for (int j = length - 1; j >= 1; j--)
9 {
10 if (arry[j] < arry[j - 1])
11 {
12 byte temp = arry[j];
13 arry[j] = arry[j - 1];
14 arry[j - 1] = temp;
15 }
16 }
17 }
18 }
19 }

以往写代码首先是要实现功能,功能实现了,下一步才是讨论如何优化。因为设计之处,大家能够想到很多很多可能面临的问题,但实际上有些问题可能永远不会发生,你却花费了大量的时间。我啰嗦这句话的意思其实是想告诉大家,不要过早的进行抽象化和应对变化。上面两个方法已经很好的解决了int和byte的问题,但是新的需求又来了,这一次需要对char类型的数组进行排序。当然可以继续copy上面的方法,可是似乎聪明的人不能接受,我们要善于总结归纳,这是曾经上学时我认为学习数学和物理最重要的方法。
    对比前面两个方法,它们除了方法的签名不同之外完全是一样的,曾经开发web的时候,在web上生成静态页面最常用的一个方式是使用模版,每次生成静态页面的时候先加载模版,模版中含有特殊的占位符,然后从数据库读取数据,使用取出的数据替换这些占位符,最后将模版按照一定的命名规范生成HTML静态文件保存在服务器上,所以服务器无需重写url,只需要把静态文件返回给客户端就好了。

基于这种思路,我们上面的方法可以视为一个模版,而int[],byte[]的位置就使用占位符来替换掉好了。

于是,把int,byte,char等等都看作是->T,T代表所有类型。

这个时候方法的签名就是下面这样了:

 public void sort(T[] arry)

但是又有问题了,T怎么知道自己是谁呢?int,byte还是其他?有人可能想到,通过类的构造方法传递T的类型,这里要说明的是,构造方法接受的参数是类型的实例,而T本身就是类型,显然无法传递它。

public Sort(类型的实例);

.NET专门定义了一种类型传递方式

1 public class SortHelper<T>      {
2 public void sort(T[] arry)
3 {
4 ......
5 }
6 }

使用方法:

1 Sort<byte> sort  = new Sort<byte>();
2 byte[] array = {8,1,4,7,3};
3 sort.sortArray(array);

此时,T知道自己是byte了,但是编译后发现错误,这是下一次要讨论的问题~

C#中的泛型-1,布布扣,bubuko.com

时间: 2024-11-03 03:27:00

C#中的泛型-1的相关文章

构造方法中使用泛型

------------siwuxie095 构造方法中使用泛型: 构造方法可以为类中的属性初始化,如果类中的属性通过泛型指定,而又需要 通过构造方法设置属性内容的时候,构造方法的定义与之前并无不同,不需要 像声明类那样指定泛型 package com.siwuxie095.generic; class Context<T>{ private T value; public Context(T value) { this.value=value; } public T getValue() {

泛型及java中的泛型

当作笔记整理的~~~ 首先,引出堆对象这个概念. 什么是堆对象,就是程序在运行过程中可以随时建立或者删除的对象,可以用new运算符(或malloc函数)或者delete运算符(或free函数).泛型可以看作是一类堆对象. 泛型是程序设计语言的一种特性.允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明. 各种程序设计语言和其编译器.运行环境对泛型的支持均不一样.将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型. 泛型的定义主要有两种:1.在程序编

Java 中的泛型详解-Java编程思想

Java中的泛型参考了C++的模板,Java的界限是Java泛型的局限. 2.简单泛型 促成泛型出现最引人注目的一个原因就是为了创造容器类. 首先看一个只能持有单个对象的类,这个类可以明确指定其持有的对象的类型 class Holder1 { private Circle a; public Holder1(Circle a) { this.a = a; } Circle get() { return a; } } 上面的类的可重用性不怎么样,无法持有其他类型的任何对象,下面通过持有Object

转载:C#中的泛型

泛型类和泛型方法兼复用性.类型安全和高效率于一身,是与之对应的非泛型的类和方法所不及.泛型广泛用于容器(collections)和对容器操作的方 法中..NET框架2.0的类库提供一个新的命名空间System.Collections.Generic,其中包含了一些新的基于泛型的容器类.要查 找新的泛型容器类(collection classes)的示例代码,请参见基础类库中的泛型.当然,你也可以创建自己的泛型类和方法,以提供你自己的泛化的方案和设计模式,这是类型安全且高效 的.下面的示例代码以一

java中的泛型(转)

什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象. 因为 Map.get(

.net中的泛型

泛型把类或方法的类型的确定推迟到实例化该类或方法的时候 ,也就是说刚开始声明是不指定类型,等到要使用(实例化)时再指定类型 泛型可以用于  类.方法.委托.事件等 下面先写一个简单的泛型 public class GenericClass<T> { void SomeMethod( T t ) { //do something } } 其使用方法如下: 实例化一个类 ? 1 GenericClass<int> gci=new GenericClass<int>(); 方

Java中的泛型 (上) - 基本概念和原理

本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以深刻理解容器类.那,泛型到底是什么呢? 什么是泛型? 一个简单泛型类 我们通过一个简单的例子来说明泛型类的基本概念.实现原理和好处. 基本概念 我们直接来看代码: public class Pair<T> { T first; T second; public Pair(T first, T se

编写高质量代码改善C#程序的157个建议——建议43:让接口中的泛型参数支持协变

建议43:让接口中的泛型参数支持协变 除了上一建议中提到的使用泛型参数兼容接口不可变性外,还有一种办法是为接口中的泛型声明加上out关键字来支持协变,如下所示: interface ISalary<out T> //使用out关键字 { void Pay(); } static void Main(string[] args) { ISalary<Programmer> s = new BaseSalaryCounter<Programmer>(); ISalary&l

ActionScript3.0(AS3)中的泛型数组Vector

Adobe官方并没有"泛型数组"的叫法,这是我自己对Vector的叫法(有点标题党),不过Vector在使用上确实跟c#中的泛型数组有些相似之处. 原作者:菩提树下的杨过出处:http://yjmyzz.cnblogs.com 我们知道:ActionScript3.0中的Array数组可以存放多种类型,甚至在同一个Array数组中,可以同时存入String,Object,Number...,但其实我们在实际开发中,通常一个数组中所保存的元素类型都是一致的,为了改进这种情况下的效率,AS

在集合中使用泛型

1 保证集合中元素类型的一致 package lianxi3; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Test; public class TestGeneric { @Test //在集合中使用泛型 pub