C# 泛型-创建自己的泛型
2013-06-18 12:06
337 查看
泛型是编程语言中的一种特性,它允许在强类型语言中,设计程序的时候不指定类型,而在使用的时候才明确类型。
说得直白点:一个方法要支持 int、decimal、string 等类型的参数,用重载?那重载也太多了吧。用 object 类型的参数?那装箱拆箱或强制类型转换操作也太浪费资源了吧,并且在编译时可能无法进行类型检查。并且我还想用同一个方法返回不同的类型值。
C# 中用泛型可以解决这些问题。C# 中泛型可用于类、结构、接口、委托,及其成员。
使用泛型举例
using System.Collections.Generic;
List<int> l1 = new List<int>();
List<string> l2 = new List<string>();
l1.Add(1);
l2.Add("a");
m = l1[0];
a = l2[0];
可以看出,List 通过泛型,既方便地处理 int 类型,也方便地处理 string 类型。
第一个泛型方法
public class C
{
public T Foo<T>(T value)
{
return value;
}
}
C c = new C();
int i = c.Foo<int>(3) + 2;
decimal d = c.Foo<decimal>(30) + 20;
MessageBox.Show(i.ToString() + "\r\n" + d.ToString());
int j = c.Foo(3); // 也是正确的,编译器将自动推断类型。
如上实现了一个泛型(虽然这个 Foo 方法代码极其简单),但是通过指定 Foo<T> 明确了参数、返回值的类型。
有人会问:
是不是非得用 T 这个字母呢?我用 T1 可以吗?可以,随便。
是不是参数中非得用 T 类型,返回值非得用 T 类型呢?完全不是,只是根据你的需要,参数你也可以直接指定 int 类型,返回值你也可以指定为 string 类型,也可以不要返回值。
同时使用多个泛型
public void Foo<T1, T2>(T1 value1, T2 value2, int value3)
默认值
由于泛型不知道使用时的类型,所以它就不知道自己将是引用类型,还是值类型(分数值类型和结构类型)。我们希望引用类型时为变量赋 null 初始值,值类型中的数值类型时为变量赋 0 初始值。方法是使用 default 关键字。
T t = default(T);
泛型不是 object
泛型不是 object,不会涉及装箱、拆箱操作,所以以下代码均是错误的:
public int Foo<T>(T value)
{
return (int)value;
}
public T Foo<T>(T value1, T value2)
{
return value1 + value2;
}
泛型类
前面介绍了泛型方法,其实泛型类、泛型接口、泛型委托的创建都类似于泛型方法,以泛型类为例。
public class C<T>
{
public T Value1 { get; set;
}
public T Value2 { get; set;
}
public C(T value1, T value2)
{
Value1 = value1;
Value2 = value2;
}
public void Swap()
{
T t = Value1;
Value1 = Value2;
Value2 = t;
}
}
C<int> c1 = new C<int>(1,
2);
C<string> c2 = new C<string>("a", "b");
c1.Swap();
c2.Swap();
MessageBox.Show(c1.Value1.ToString() + c1.Value2.ToString() + c2.Value1 + c2.Value2);
http://www.cftea.com/c/2012/04/5535.asp
说得直白点:一个方法要支持 int、decimal、string 等类型的参数,用重载?那重载也太多了吧。用 object 类型的参数?那装箱拆箱或强制类型转换操作也太浪费资源了吧,并且在编译时可能无法进行类型检查。并且我还想用同一个方法返回不同的类型值。
C# 中用泛型可以解决这些问题。C# 中泛型可用于类、结构、接口、委托,及其成员。
使用泛型举例
using System.Collections.Generic;
List<int> l1 = new List<int>();
List<string> l2 = new List<string>();
l1.Add(1);
l2.Add("a");
m = l1[0];
a = l2[0];
可以看出,List 通过泛型,既方便地处理 int 类型,也方便地处理 string 类型。
第一个泛型方法
public class C
{
public T Foo<T>(T value)
{
return value;
}
}
C c = new C();
int i = c.Foo<int>(3) + 2;
decimal d = c.Foo<decimal>(30) + 20;
MessageBox.Show(i.ToString() + "\r\n" + d.ToString());
int j = c.Foo(3); // 也是正确的,编译器将自动推断类型。
如上实现了一个泛型(虽然这个 Foo 方法代码极其简单),但是通过指定 Foo<T> 明确了参数、返回值的类型。
有人会问:
是不是非得用 T 这个字母呢?我用 T1 可以吗?可以,随便。
是不是参数中非得用 T 类型,返回值非得用 T 类型呢?完全不是,只是根据你的需要,参数你也可以直接指定 int 类型,返回值你也可以指定为 string 类型,也可以不要返回值。
同时使用多个泛型
public void Foo<T1, T2>(T1 value1, T2 value2, int value3)
默认值
由于泛型不知道使用时的类型,所以它就不知道自己将是引用类型,还是值类型(分数值类型和结构类型)。我们希望引用类型时为变量赋 null 初始值,值类型中的数值类型时为变量赋 0 初始值。方法是使用 default 关键字。
T t = default(T);
泛型不是 object
泛型不是 object,不会涉及装箱、拆箱操作,所以以下代码均是错误的:
public int Foo<T>(T value)
{
return (int)value;
}
public T Foo<T>(T value1, T value2)
{
return value1 + value2;
}
泛型类
前面介绍了泛型方法,其实泛型类、泛型接口、泛型委托的创建都类似于泛型方法,以泛型类为例。
public class C<T>
{
public T Value1 { get; set;
}
public T Value2 { get; set;
}
public C(T value1, T value2)
{
Value1 = value1;
Value2 = value2;
}
public void Swap()
{
T t = Value1;
Value1 = Value2;
Value2 = t;
}
}
C<int> c1 = new C<int>(1,
2);
C<string> c2 = new C<string>("a", "b");
c1.Swap();
c2.Swap();
MessageBox.Show(c1.Value1.ToString() + c1.Value2.ToString() + c2.Value1 + c2.Value2);
http://www.cftea.com/c/2012/04/5535.asp
相关文章推荐
- 从零开始编写自己的C#框架(9)——数据库设计与创建
- 按自己的想法去理解事件和泛型(C#)
- c# 无法引用自己创建的类库
- 从零开始编写自己的C#框架(9)——数据库设计与创建
- 用C#和microsoft webbrowser控件创建自己的ie
- c#创建静态类,在其中定义一个泛型方法,实现查找数组元素的功能
- C#中通过读取配置文件动态创建泛型对象
- C#中通过读取配置文件动态创建泛型对象
- C#集合,泛型,以及自定义排序自己总结1
- C#创建自定义泛型结构和类
- 如何:为泛型列表创建迭代器块(C# 编程指南)
- C#中自己动手创建一个Web Server(非Socket实现)
- C#中用Microsoft Agent为自己的程序创建精灵助手
- C#通过反射来动态创建类对象并调用相关泛型函数(Excel数据自动导入到SQL Server数据库)
- C#创建自己的DLL(动态链接库)
- C# Owin 创建与测试自己的中间件Middleware(二)
- 1.创建泛型 类-C#高级编程
- C#队列泛型基类BaseQueue,访问索引器时自动创建类型实例
- C# 创建自己的日志记录类(源码)
- C#中自己动手创建一个Web Server(非Socket实现)