浅谈c# 泛型类的应用分析

浅谈c# 泛型类的应用分析
浅谈c# 泛型类的应用分析

浅谈c# 泛型类的应用

本篇文章是对c#中泛型类的应用进行了详细的分析介绍,需要的朋友参考下

泛型类

泛型类封装不是特定于具体数据类型的操作。泛型类最常用于集合,如链接列表、哈希表、堆栈、队列、树等。像从集合中添加和移除项这样的操作都以大体上相同的方式执行,与所存储数据的类型无关。对大多集合类的操作,推荐使用.NET Framework 类库中所提供的类。

(1)泛型类可以继承具体类、封闭式构造、开放式构造基类。

复制代码代码如下:

class BaseNode { }

class BaseNodeGeneric { }

// 继承具体类

class NodeConcrete : BaseNode { }

//继承封闭式构造基类

//封闭式构造基类指基类类型参数指定具体类型

class NodeClosed : BaseNodeGeneric { }

//继承开放式构造基类

//开放式构造基类指基类类型参数未指定

class NodeOpen : BaseNodeGeneric { }

(2)基类类型参数必须在子类中指定实现。

复制代码代码如下:

//正确

class Node1 : BaseNodeGeneric { }

//错误

//在子类中未指定父类类型参数实现

class Node2 : BaseNodeGeneric {}

//错误

//在子类中未指定父类类型参数实现

class Node3 : T {}

class BaseNodeMultiple { }

//正确

class Node4 : BaseNodeMultiple { }

//正确

class Node5 : BaseNodeMultiple { }

//错误

//在子类中未指定父类类型参数实现

class Node6 : BaseNodeMultiple {}

(3)从开放式构造类型继承的泛型类必须指定约束,这些约束是基类型约束的超集或暗示基类型约束。

复制代码代码如下:

class NodeItem where T : System.IComparable, new() { }

class SpecialNodeItem : NodeItem where T : System.IComparable, new() { }

(4)泛型类型可以使用多个类型参数和约束。

复制代码代码如下:

class SuperKeyType

where U : System.IComparable

where V : new()

{ }

(5)开放式构造类型和封闭式构造类型可以用作方法参数。

复制代码代码如下:

void Swap(List list1, List list2)

{ }

void Swap(List list1, List list2)

{ }

泛型接口

(1)泛型类型参数可指定多重接口约束。

复制代码代码如下:

class Stack where T : System.IComparable, IEnumerable

{

}

(2)接口可以定义多个类型参数。

复制代码代码如下:

interface IDictionary

{

}

(3)类继承规则适用接口继承规则。(参考上面泛型类继承)(4)泛型接口实例

复制代码代码如下:

class GenericInterface

{

static void Main()

{

SortedList list = new SortedList();

string[] names = https://www.360docs.net/doc/0117049410.html,new string[]

{

"zhang san",

"li si",

"wang wu",

"zhou er",

"he yi"

};

int[] ages = new int[] { 22, 15, 30, 34, 12 };

for (int x = 0; x < 5; x++)

{

list.AddNode(new Person(names[x], ages[x]));

}

foreach (Person p in list)

{

System.Console.WriteLine(p.ToString());

}

Console.WriteLine("------------------排序-----------------------");

list.BublleSort();

foreach (Person p in list)

{

System.Console.WriteLine(p.ToString());

}

Console.Read();

}

}

public class GenericList : System.Collections.Generic.IEnumerable {

public class Node

{

private T data;

public T Data

{

get { return data; }

set { data = value; }

}

private Node next;

public Node Next

{

get { return next; }

set { next = value; }

}

private Node last;

public Node Last

{

get { return last; }

set { last = value; }

}

public Node(T t)

{

data = t;

next = null;

}

}

public Node firstNode;

private Node lastNode;

public void AddNode(T t)

{

Node node = new Node(t);

https://www.360docs.net/doc/0117049410.html,st = lastNode;

if (lastNode != null)

lastNode.Next = node;

lastNode = https://www.360docs.net/doc/0117049410.html,node;

if (firstNode == null)

firstNode = node;

}

#region IEnumerable 成员

public IEnumerator GetEnumerator()

{

Node current = firstNode;

while (current != null)

{

//yield return表达式以枚举对象返回

yield return current.Data;

current = current.Next;

}

}

#endregion

#region IEnumerable 成员

//IEnumerable < T >继承自IEnumerable,

//因此这类必须实现泛型和非泛型的版本的GetEnumerator。

//在大多数情况下,非泛型方法简单调用泛型方法。

IEnumerator IEnumerable.GetEnumerator()

{

return GetEnumerator();

}

#endregion

}

public class SortedList : GenericList where T : System.IComparable {

//该方法实现排序

public void BublleSort()

{

if (firstNode == null || firstNode.Next == null)

return;

bool swapped;

do

{

Node last = null;

Node current = firstNode;

swapped = false;

while (current.Next != null)

{

if (https://www.360docs.net/doc/0117049410.html,pareTo(current.Next.Data) > 0)

{

/* 当前节点大于下一个节点,位置交换*/

Node tmp = current.Next;

current.Next = current.Next.Next;

tmp.Next = current;

if (last == null)

{

firstNode = tmp;

}

else

{

last.Next = tmp;

}

last = tmp;

swapped = true;

}

else

{

last = current;

current = current.Next;

}

}

}

while (swapped);

}

}

public class Person : System.IComparable

{

string name;

int age;

public Person(string n, int a)

{

name = n;

age = a;

}

#region IComparable 成员

public int CompareTo(Person p)

{

//按年龄排序

//return age - p.age;

//按名称排序

int a =https://www.360docs.net/doc/0117049410.html,pareTo(https://www.360docs.net/doc/0117049410.html,);

return a;

}

#endregion

public override string ToString()

{

return name + ":" + age;

}

}

输出如下:

泛型方法

包含类型参数声明的方法即为泛型方法。

(1)泛型类的类型参数与它内部泛型方法的类型参数一致,编译器将生成警告CS0693。复制代码代码如下:

class GenericList

{

// CS0693

void SampleMethod() { }

}

(2)泛型方法的类型参数可以进行约束。

(3)泛型方法可以使用许多类型参数进行重载。

复制代码代码如下:

void DoWork() { }

void DoWork() { }

void DoWork() { }

通过实例学习C#开发中的泛型

C#中所谓泛型:即通过参数化类型来实现在同一份代码上操作多种数据类型。泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。 C#泛型赋予了代码更强的类型安全,更好的复用,更高的效率,更清晰的约束。 C#泛型机制简介 C#泛型能力由CLR在运行时支持,区别于C++的编译时模板机制,和java 的编译时的“搽拭法”。这使得泛型能力可以在各个支持CLR的语言之间进行无缝的互操作。 C#泛型代码在被编译为IL和元数据时,采用特殊的占位符来表示泛型类型,并用专有的IL指令支持泛型操作。而真正的泛型实例化工作以“on-demand”的方式,发生在JIT编译时。 C#泛型编译机制 第一轮编译时,编译器只为Stack类型产生“泛型版”的IL代码和元数据,并不进行泛型类型的实例化,T在中间只充当占位符。 JIT编译时,当JIT编译器第一次遇到Stack时,将用int类型替换“泛型版”IL代码与元数据中的T -- 进行泛型类型的实例化。 CLR为所有类型参数为“引用类型”的泛型类型产生同一份代码,但如果类型参数为“值类型”,对每一个不同的“值类型”,CLR将为其产生一份独立的代码。 C#泛型的几个特点 如果实例化泛型类型的参数相同,那么JIT编译器会重复使用该类型,因此C#的动态泛型能力避免了C++静态模板可能导致的代码膨胀的问题。 C#泛型类型携带有丰富的元数据,因此C#的泛型类型可以应用于强大的反射技术。 C#的泛型采用“基类、接口、构造器、值类型/引用类型”的约束方式来实现对类型参数的“显示约束”,提高了类型安全的同时,也丧失了C++模板基于“签名”的隐式约束所具有的高灵活性。 C#泛型类与结构 class C{} //合法 class D:C{} //合法

第8章_泛型编程习题_参考答案

《面向对象程序设计》习题 第8章泛型编程 一、选择题(共40分,每题2分) 二、填空题(共20分,每空2分) 1. 逻辑数据类型 2. 函数类 3. 函数模板类模板 4.函数类型形参类型 5.2 6. 尖括号 三、下列程序有2个错,找出并修改(共6分) 错1:public: A(T a, b) // A(T a,T b) {x=a,y=b;s=x+y;} 错2: int main() { A add(10,100); // A add(10,100); add.show(); return 0; } 四、看程序写结果(共12分,每题4分) 1. 2. 3.

五、编程题(22分) 1.设计一个函数模板,实现两数的交换,并用int、float、double、char类型的数据进行测试。 #include #include using namespace std; template void change(T &x, T &y) { T temp; temp=x; x=y; y=temp; } int main() { int a=12, b=34; float c=1.1, d=2.2; double e=1.23456789, f=2.23456789; char u='A', v='B'; cout<<"交换前:a="< 19/// 20public T this[int index] 21 { 22get 23 { 24if (index >= arr.Length) 25 { 26throw new System.Exception("数组下标越界 "); 27 } 28else

29 { 30return arr[index]; 31 } 32 } 33set 34 { 35if (index >= arr.Length) 36 { 37throw new System.Exception("数组下标越界 "); 38 } 39else 40 { 41 arr[index]=value; 42 } 43 } 44 } 45 } 调用: 1protected void Page_Load(object sender, EventArgs e) 2 { 3 MyList list = new MyList(4); 4 5 list.Add(1); 6 list.Add(4); 7 list.Add(5); 8 list.Add(6); 9for (int i = 0; i < list.count; i++) 10 { 11 Response.Write(list[i].ToString()); 12 } 13 } 注意: 1、是在运行时,将堆空间里的对象内部所有的占位符都替换成传入的类型. 2、泛型是指带类型参数的类,而不是类型参数本身。

C#泛型探究(自学篇)

前言 前几日同学告诉我他老师告诉他,泛型是定义一种通用的方法,至于为什么用泛型他的答 案还是定义一种通用的方法,当时我也没有学,还不懂啦,毕竟人家是计算机专业的科班生,我当 然没有发言权,只是怀疑的记下了这个错误的结论打算以后看看是不是对的,这两天算是把泛型学 了一下,其实它定义的不只是方法,自己感觉他就是一种规范代码执行效率的模版,这样极不容易 出错,并把我们常用的箱拆箱操作过程给省了,提高了编译器的执行效率,。至于为什么用泛型这 个我貌似已经说明白了,泛型多用于集合类操作,我在这里随意的拿出C#定义的ArrayList的 Add方法的定义我们一起看看: public virtual int Add( Object value ) 可以看出我们可以往ArrayList里添加任何类型的元素,假如有一个string类型的str字符 串它在添加到ArrayList lib的过程中实际进行了装箱操作,即object value=str;那么我 们在获取这个值得时候必须这样使用string s=(string)lib[0];不能遗漏(string)否则会提示你, 错误1无法将类型“object”隐式转换为“string”。存在一个显式转换(是否缺少强制转换?) 但是你假如这样写:int a=(int)lib[0];程序在运行前是无法报错的,只要一旦运行就会出 现异常,而这些错误都可以利用泛型轻松搞定,让你在编译时就可以发现错误,具体的就看你怎么 领悟了,我在文章里没有写任何定义的语法格式,因为这个既没必要说,这是常识,出来混这些迟 早是要明白的,呵呵。玩笑啦......欢迎新手同学来我的博客交流学习,我也希望你们可以为我敞 开心怀,因为我既不是计算机专业的学生,甚至上了大学我已经不再是理工类的学生。我无意扎进了 文科专业去叱咤风云啦,哎,这个文科专业名字太有点科学技术的味道了。我喜欢 ........ 我的博客地址是:https://www.360docs.net/doc/0117049410.html,

c代码规范

c代码规范(总7页) -CAL-FENGHAI.-(YICAI)-Company One1 -CAL-本页仅作为文档封面,使用请直接删除

C# 代码规范 1、前言 本文档定义了一些通用的代码规范和准则,一般情况下本文档适用于项目组所有项目,特殊情况下,如果客户有自己的代码规范,以客户的代码优先。 2、大小写约定 2.1、大小写样式,本文中将出现两种大小写样式,这里先分别定义: Pascal大小写 将标识符的首字母和后面连接的每个单词的首字母都大写。可以对三字符或更多字符的标识符使用 Pascal 大小写。例如:BackColor Camel大小写 标识符的首字母小写,而每个后面连接的单词的首字母都大写。例如:backColor 匈牙利命名法 基本原则是:变量名=属性+类型+对象描述。例如:lblName 2.2、标识符大小写规则 2.2.1、下表中列出常见的代码元素的样式规范和示例 标识符规则示例 类Pascal AppDomain 枚举类型Pascal ErrorLevel 枚举值Pascal Warning 事件Pascal ValueChanging, ValueChanged 异常类Pascal WebException 只读的静态字段Pascal CurrentUser 接口Pascal IDisposable 方法Pascal ToString 命名空间Pascal 参数Camel typeName 属性Pascal Name 常量全大写MAXLENGTH, LENGTH_MAX Web或Win控件匈牙利txtName 2.2.2、除了遵循以上大小写约定外还需注意以下约定(除常量为特例): 如果标识符由多个单词组成,请不要在各单词之间使用分隔符,如下划线(“_”)或连字符(“-”)等。而应使用大小写来指示每个单词的开头。 所有公共的成员如:方法、属性,都应使用Pascal大小写样式 2.3、首缩写词的大小写规则 2.3.1、首字母缩写词 首字母缩写词是由术语或短语中各单词的首字母构成的单词。 例如,HTML 是 Hypertext Markup Language 的首字母缩写。为了方便编码规范的实施,本文规定受字母缩写词必须至少为两个单词,正好为两个单词的首字母缩写词称其为“短型首字母缩写词”,两个单词以上的称其为“长型首字母缩写词” 2.3.2、单缩写词

【个人总结系列-47】C C++编程注意问题总结-模板和泛型编程-结构体注意-中文字符读取-产生随机数

C/C++编程注意问题总结-模板和泛型编程-结构体注意-中文字符读 取-产生随机数 1.1.1 C++模板和泛型编程总结 ?函数模板:函数中有不确定的类型T(或成为模板类型) template T1 fun(T2 n) 函数模板在调用时自动根据参数的类型判断产生哪种类型的实例。所以程序员必须自己保证在函数中的类型T能够胜任所参与的运算。比如在函数fun()中有T类型的两个数据进行+运算,则程序员必须保证参数能够进行+运算。 ?类模板 类模板:类中有不确定的类型T(或成为模板类型) template class Person{} 类中函数在类外部的实现:必须在每个函数上面加一个template,以及在类后面用<>说明类中用到的模板类型T,如下所示: template Person::int getAge(){} 类模板在实例化时(声明和new一个类模板时),必须用<具体的T>注明类的类型。 凡是实例化一个类模板时(即用这种类时),必须要注明具体的类型。如: Person p; new的时候 Person p = new Person("Jim",20); 1.1.2 结构体需要注意的问题 ?结构指针 结构指针:struct string *student; 实际上, student->name就是(*student).name的缩写形式。 需要指出的是结构指针是指向结构的一个指针, 即结构中第一个成员的首地址,因此 在使用之前应该对结构指针初始化,即分配整个结构长度的字节空间, 这可用下面函数完成, 仍以上例来说明如下: student=(struct string*)malloc(sizeof (struct string)); 结构变量struct string student1,访问时https://www.360docs.net/doc/0117049410.html,; 结构变量指针struct string *student2,访问时student2->name;或 (*student2).name ?结构体的创建和初始化 New与malloc一个结构体: Struct string *student=(struct string*)malloc(sizeof (struct string)); Struct string *student = new string;

java中的泛型

Java中的泛型 JDK1.5令我们期待很久,可是当他发布的时候却更换版本号为5.0。这说明Java已经有大幅度的变化。本文将讲解JDK5.0支持的新功能-----Java的泛型. 1、Java泛型 其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型也是一样的,这样写class Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和str2,也是可变。下面看看例子: 正确输出:value 这只是个例子(Java中集合框架都泛型化了,这里费了2遍事.),不过看看是不是创建一个用类型作为参数的类,参数是K,V,传入的“值”是String类型。这个类他没有特定的待处理型别,以前我们定义好了一个类,在输入输入参数有所固定,是什么型别的有要求,但是现在编写程序,完全可以不制定参数的类型,具体用的时候来确定,增加了程序的通用性,像是一个模板。 呵呵,类似C++的模板(类似)。 1.1. 泛型通配符 下面我们先看看这些程序:

看看这个方法有没有异议,这个方法会通过编译的,假如你传入String,就是这样List <String>。 接着我们调用它,问题就出现了,我们将一个List<String>当作List传给了方法,JVM会给我们一个警告,说这个破坏了类型安全,因为从List中返回的都是Object类型的,而让我们再看看下面的方法。 因为这里的List<String>不是List<Object>的子类,不是String与Object的关系,就是说List<String>不隶属于list<Object>,他们不是继承关系,所以是不行的,这里的extends是表示限制的。 类型通配符是很神奇的,List<?>这个你能为他做什么呢?怎么都是“?”,它似乎不确定,他总不能返回一个?作为类型的数据吧,是啊他是不会返回一个“?”来问程序员的?JVM会做简单的思考的,看看代码吧,更直观些。 这段代码没问题的,l1.get(0)将返回一个Object。 1.2. 编写泛型类要注意: 1) 在定义一个泛型类的时候,在“<>”之间定义形式类型参数,例如:“class TestGen <K,V>”,其中“K” , “V”不代表值,而是表示类型。 2) 实例化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。例如: TestGen<String,String> t=new TestGen<String,String>();

实验七 C#泛型

实验七泛型 实验学时:2学时 实验类型:验证 实验要求:必做 一、实验目的 1.掌握泛型的基本使用; 2.声明和使用泛型方法 二、实验内容 实验1使用泛型List创建各种类型的列表 实验要求:参照课本例11.2,使用泛型List创建并显示整型数组列表ArrayList1:1,3,5;字符串型数组列表ArrayList2:”One”,”Two”,”Three”。 源程序: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace fanxing { class Program { static void Main(string[] args) { List list1 = new List(); list1.Add(1); list1.Add(3); list1.Add(5); Console.WriteLine("整数数组列表ArrayList1的内容如下:"); foreach (int x in list1) { Console.WriteLine(x); } List list2 = new List(); list2.Add("One"); list2.Add("Two"); list2.Add("Three"); 1

Console.WriteLine("字符串型数组列表ArrayList2的内容如下:"); foreach (string s in list2) { Console.WriteLine(s); } Console.ReadLine(); } } } 运行结果: 实验2 声明和使用泛型方法 实验要求:参照课本例11.5,声明泛型方法Swap,实现两个数内容的交换。在main ()中输入任意两个整数和任意两个实数,分别调用泛型方法Swap,实现整数内容的交换和实数内容的交换。 源程序: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace fanxingfangfa { class Program { static void Swap(ref T lhs, ref T rhs) { T temp; temp = lhs; lhs = rhs; rhs = temp; } static void Main(string[] args) { Console.WriteLine("请输入任意两个整数:"); int a, b; String s = Console.ReadLine(); a = int.Parse(s); s = Console.ReadLine();

新泛型)

基于泛型DAO的spring和hibernate的集成(转) 编写Spring+Hibernate框架下的应用,总是离不了编写一个通用的泛型GenericHibernateDao。查阅了网上不少的GenericHibernateDao实现,归纳整理为如下实现,供后续编码参考。 首先定义接口泛型DAO接口GenericDao package com.th.huz; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.hibernate.Criteria; import org.hibernate.LockMode; import org.hibernate.criterion.DetachedCriteria; public interface GenericDao { // -------------------- 基本检索、增加、修改、删除操作-------------------- // 根据主键获取实体。如果没有相应的实体,返回null。 public T get(PK id); // 根据主键获取实体并加锁。如果没有相应的实体,返回null。 public T getWithLock(PK id, LockMode lock); // 根据主键获取实体。如果没有相应的实体,抛出异常。 public T load(PK id); // 根据主键获取实体并加锁。如果没有相应的实体,抛出异常。 public T loadWithLock(PK id, LockMode lock); // 获取全部实体。 public List loadAll(); // loadAllWithLock() ? // 更新实体 public void update(T entity); // 更新实体并加锁 public void updateWithLock(T entity, LockMode lock); // 存储实体到数据库

C++模板函数与Java泛型

C++模板函数 #include "iostream" using namespace std; intint_ab(inta,int b) { returna+a*b; } doubledouble_ab(double a,double b) { returna+a*b; } int main(){ cout<或者template来定义一个任意类型的数据T,定义后的函数必须紧跟着。 #include "iostream" using namespace std; template T1 ab(T1 a,T1 b) { returna+a*b; } int main(){ cout< T1 ab(T1 a,T1 b)

8. Java基础_泛型

泛型 1. 介绍 下面是那种典型用法: List myIntList = new ArrayList();// 1 myIntList.add(new Integer(0));// 2 Integer x = (Integer) myIntList.iterator().next();// 3 第3 行的类型转换有些烦人。通常情况下,程序员知道一个特定的list 里边放的是什么类型的数据。但是,这个类型转换是必须的(essential)。编 译器只能保证iterator 返回的是Object 类型。为了保证对Integer 类型变量赋值的类型安全,必须进行类型转换。 当然,这个类型转换不仅仅带来了混乱,它还可能产生一个运行时错误(run time error),因为程序员可能会犯错。 程序员如何才能明确表示他们的意图,把一个list(集合) 中的内容限制 为一个特定的数据类型呢?这就是generics 背后的核心思想。这是上面程序片断的一个泛型版本: List myIntList = new ArrayList(); // 1 myIntList.add(new Integer(0)); // 2 Integer x = myIntList.iterator().next(); // 3 注意变量myIntList 的类型声明。它指定这不是一个任意的List,而是 一个Integer 的List,写作:List。我们说List 是一个带一个类型参数的泛型接口(a generic interface that takes a type parameter),本 例中,类型参数是Integer。我们在创建这个List 对象的时候也指定了一个类型参数。 另一个需要注意的是第 3 行没了类型转换。 现在,你可能认为我们已经成功地去掉了程序里的混乱。我们用第1 行的类型参数取代了第 3 行的类型转换。然而,这里还有个很大的不同。编译器现在能够在编译时检查程序的正确性。当我们说myIntList 被声明为List类型,这告诉我们无论何时何地使用myIntList 变量,编译器保证其中的元素的正确的类型。 实际结果是,这可以增加可读性和稳定性(robustness),尤其在大型的 程序中。 2. 定义简单的泛型 下面是从java.util包中的List接口和Iterator 接口的定义中摘录的片断:public interface List { void add(E x); Iterator iterator(); } public interface Iterator {

Java泛型实现单链表

学号11710115 天津城建大学 Java 语言程序设计C 实验报告 实验3:泛型实现链表 学生姓名路江飞 班级11卓越七班

一、实验内容 1.掌握使用Java语言进行结构化程序设计; 2.熟悉Java泛型。 3.熟悉Eclipse开发环境,编写简单的Application程序,并编译和执行。 二、实验要求 1.调试程序、编译,运行后得到正确的结果; 2.写出实验报告,要求记录编译和执行Java程序当中的系统错误信息提示,并给出解决办法。 三、实验结果 文件1: package _List; class Node{ E e; Node next; Node(E e){ this.e=e; next=null; } } 文件2: package _List; public class Show { void print(){ System.out.println("*************************************"); System.out.println("* 1.按位查找*"); System.out.println("* 2.按值查找*"); System.out.println("* 3.插入*"); System.out.println("* 4.按位删除*"); System.out.println("* 5.按值删除*"); System.out.println("* 6.修改*"); System.out.println("* 7.遍历*");

System.out.println("* 8.查看链表长度*"); System.out.println("* 9.退出*"); System.out.println("*************************************"); } } 文件3: package _List; import java.util.Scanner; public class List { Node head; List(){ this.head=null; } List(E e[],int n){ //构造函数 this.head=new Node (e[0]); Node r=this.head; for(int i=1;is=new Node (e[i]); r.next=s; r=s; } r.next=null; } void add (E e){//按位置插入 int index,b=1; Scanner input=new Scanner(System.in); for(int j=0;b==1;j++){ System.out.print("请输入插入的位置(第一个数据之前是0号位置,以此类推):");

泛型指针

局部变量在栈里面,全局变量在堆里面。 void*(*start_rtn)(void)怎么理解,返回值是什么类型,求高手指点 这是声明一个函数指针,该函数指针指向一个无参,返回值为void *指针的函数。 泛型指针 通常情况下,C只允许相同类型的指针之间进行转换。例如:一个字符型指针sptr(一个字符串)和一个整型指针iptr,我们不允许把sptr转换为iptr或把iptr转换为sptr。但是,泛型指针能够转换为任何类型的指针,反之亦然。因此,如果有一个泛型指针gptr,就可以把sptr转换为gptr或者把gptr转换为sptr。在C语言中,通常声明一个void指针来表示泛型指针。 很多情况下void指针都是非常有用的。例如:C标准函数库中的memcpy函数,它将一段数据从内存中的一个地方复制到另一个地方。由于memcpy可能用来复制任何类型的数据,因此将它的指针参数设定为void指针是非常合理的。void指针同样也可以用到其他普通的函数中。例如:之前提到过的交换函数swap2,可以把函数参数改为void指针,这样swap2就变成一个可以交换任何类型数据的通用交换函数,代码如下: 1#include 2#include 3int swap2(void *x, void *y, int size) 4{ 5 void *tmp; 6 7 if ((tmp = malloc(size)) == NULL) 8 return -1; 9 10 memcpy(tmp, x, size); memcpy(x, y, size); memcpy(y, tmp, size); 11 free(tmp); 12 13 return 0; 14} void指针在用来实现数据结构时是非常有用的,因为可以通过void指针存储和检索任何类型的数据。我们再来看一下之前提到过的链表结构ListElmt,回想一下,这个结构包含两个成员:data和next。如果data被声明为一个void指针,那么data就可以指向任何类型的数据。从而,我们就可以使用ListElmt结构来建立各种不同数据类型的链表。

泛型程序设计与STL(简体版)

大局观:泛型程序设计( Generic Programming)与 STL 侯捷 jjhou@https://www.360docs.net/doc/0117049410.html,.tw https://www.360docs.net/doc/0117049410.html, => 1. 大局观:泛型程序设计与 STL 2. 泛型指标(Iterators)与 Traits 技术 3. 泛型容器(Containers)的应用与实作 4. 泛型算法( Generic Algorithms)与 Function Objects 5. 各色各样的 Adaptors 2000.02 2000.03 2000.04 2000.05 2000.06 十年前赶上 OO(Object Oriented,面向对象)第一波工业浪潮的朋友们,想必今日有一番顾盼豪情,以及一份「好加在」的惊悚:「好加在」搭上了 OO 的早班列车,不然今天就玩不下去了! 面对 Generic Programming(泛型程序设计),我有相彷的感觉。 我将撰写为期五次的系列文章,为各位介绍这个不算新却又有点新的观念与技术。 ●C++ Template, Generic programming, STL 1968 Doug McIlroy发表其著名论文 "Mass Produced Software Components",揭橥了以「可重用软件组件(又称软件积木或软件 IC)」构筑标准链接库的愿景。如今三分之一个世纪已逝,components software -- 以组件(组件)为本的软件 --大行其道。然而在许多领域中,标准化仍未建立。甚至连任何软件一定会用到的基本数据结构和基本算法,对此亦付阙如。于是大量的程序员,被迫进行大量重复的工作,为的竟只是重复完成前人早已完成而自己手上并未拥有的码。这不但是人力资源的浪费,也是挫折与错误的来源。 撇开追求技术的热诚不谈(也许有人确实喜欢什么都自己来),商用链接库可以拯救这些程序员于水深火热之中。只要你的老板愿意花一点点钱,就可以在人力资源与软件开发效率上取得一个绝佳平衡。但是金钱并非万能,商用链接库彼此之间并无接口上的标准!换句话说你无法在发现了 另一套更好、更丰富、效率更高的链接库后,改弦更张地弃此就彼--那可能会使你付出惨烈的代价。这或许是封闭型技术与观念带给软件组件公司的一种小小的、短暂的利益保护。 除了「接口无标准」这一问题,另一个问题是,目前绝大部份软件组件都使用面向对象技术,大量运用继承与虚拟函式,导致执行成本增加。此外,一旦运用面向对象技术,我们此刻所说的基础数据结构及各种基础算法,便皆需以 container(容器,放置数据的某种特殊结构)为本。资料,放在 container classes 内(形成其data members);操作行为,亦定义在 container classes 内(形成其 member functions);这使得耦合(coupling,两物过度相依而不独立)的情况依然存在,妨碍了组件之所以为组件的独立性、弹性、互操作性(相互合作性,interoperability)。 换句话说,要解决这些困境,第一需要标准接口的建立,第二需要 OO 以外的新技术,俾能够比 OO更高效率地 完成工作。 C++ template是新技术的曙光。 一言以蔽之,所谓 template机制就是,将目标物的数据型别参数化。一旦程序以指定自变量的方式,确定了这个(或这些)型别,编译程序便自动针对这个(或这些)型别产生出一份实体。这里所说的实体,可以是一个 function body,也可以是一个 class body。而「由编译程序产生出一份实体」的动作,我们称之为具现化(instantiation)。 针对目标物之不同,C++ 支持 function templates 和 class templates两大类型。后者的 members又可以是 templates(所谓 member templates),形成深 一

C# 自定义泛型集合Generic Collection类

C# 自定义泛型集合Generic Collection类using System; using System.Collections.Generic; using System.Text; namespace CustomGenericCollection { #region Automobile definitions public class Car { public string PetName; public int Speed; public Car(string name, int currentSpeed) { PetName = name; Speed = currentSpeed; } public Car() { } } public class SportsCar : Car { public SportsCar(string p, int s) : base(p, s) { } // Assume additional SportsCar methods. } public class MiniVan : Car { public MiniVan(string p, int s) : base(p, s) { } // Assume additional MiniVan methods. } #endregion #region Custom Generic Collection //下面的泛型集合类的项目必须是Car 或Car的继承类 public class CarCollection : IEnumerable where T : Car { private List arCars = new List(); public T GetCar(int pos) { return arCars[pos]; }

泛型实验要求

泛型实验 实验时间:2009年3月2 实验目的: 掌握泛型与其他集合相比的优势,创建泛型类,泛型方法,可空类型的运用,编译程序集的方法。 实验准备: 打开VS2005,新建一个空白解决方案,命名为lab2,存储在d盘根目录。 实验内容: 一,泛型与集合安全的比较 1,在解决方案里面,新建一个控制台应用程序命名为ListArray 2, 在Program.cs的入口函数中,创建一个ArrayList集合,往集合里面添加2个Int数字,再添加一个double数字 3, 再定义一个int变量total初始值为0 4, 利用循环语句foreach把集合里面的int变量相加的和存入total

5, 输出total的值,预览下效果 思考:如果出错,出错的原因在哪,如何更改 6,注释掉上面代码,通过同样的方法,定义一个泛型List,实现同样的目的,测试调试,比较下2种方法有什么区别和进步的地方。 二,创建泛型类 1,在解决方案里面再新建一个控制台应用程序命名为ListClass,设置为启动项 2, 新建一个类,命名为ListTest,在类中创建一个名称称为MyList 泛型类,为把它参数化,插入一个尖括号。在<>内的添加T代表使用该类时要指定的类型 3, 在MyList类中定义一个静态字段ObjCount,初始值为0,在构造器中实现自加,实现功能:计算用户实例化了多少个不同类型的对象。再创建一个属性字段getCount用于取得静态字段ObjCount 的值 4, 在Program.cs的入口函数Main中,实例2个int类型的MyList 类,1个double类型的Mylist类,用控制台输出每个实例的getCount属性。 思考:getCount的值有什么特性?泛型类的优势

相关主题