• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
我就是停不下来
业精于勤荒于嬉,行成于思毁于随
博客园    首页    新随笔    联系   管理    订阅  订阅

泛型

c#2.0比c#1.0有一点最大的改进就是加入对泛型的支持。泛型起源于c++语言的模板机制。这样在c#中就避免了不必要的拆装箱操作,而且还加强了编译时的安全性,强类型的检查。

CLR#允许创建泛型引用类型,值类型,但是不许创建泛型枚举类型。 还可以创建泛型接口,委托,以及最常见的泛型方法。

//c#中的泛型集合类:
List<T>
Dictionary
<TKey, TValue>
SortedDictionary
<TKey, TValue>
Stack
<T>
Queue
<T>
LinkedList
<T>

//c#中的泛型接口:
IList<T>
IDictionary
<TKey, TValue>
IConection
<T>
IEnumerator
<T>
IEnumerable
<T>
IComparer
<T>
IComparable
<T>

下面展示如何使用其中的一些泛型方法:

public static void Main() ...{
Byte[] byteArray 
= new Byte[] ...{5, 1, 4, 2, 3}
;
Array.Sort
<Byte>
(byteArray);
Int32 i 
= Array.BinarySearch<Byte>(byteArray, 1
);
Console.WriteLine(i);                                                              
// Displays "0"

}

下面看一下泛型的同一性:

internal sealed class DateTimeList : List<DateTime> ...{
}

DateTimeList dt 
= new DateTimeList();                                            //这样写省去了<>括号,看起来简便了

 
/**//*这样会返回false,也就是如果一个方法参数允许接受DateTimeList类型,那么我们不可以把List<DateTime>传给他,因为这两个类型不相等,但是如果一个方法参数允许接受List<DateTime>类型,那么可以把一个DateTimeList传过去,因为他们之间存在继承关系*/
Boolean sameType 
= (typeof(List<DateTime>) == typeof(DateTimeList));                     

//如果我们想简便写法,可以像下面这样写:

using DateTimeList = System.Collections.Generic.List<System.DateTime>;
Boolean sameType 
= (typeof(List<DateTime>) == typeof(DateTimeList));                             //返回true



记住显示的方法优于泛型方法被调用:

void Swap<T>(T arg1,Targ2)
...
{
           Console.Write(
"Generic"
);
}


void Swap(double arg1,double,arg2)
...
{
              Console.Write(
"Common"
);
}


//下面将会调用第二个方法
Swap(12.36,36.21);

下面看一下泛型约束,这一点是c#泛型的优势:

约束分为三种:主要约束,次要约束,和构造器约束

/**//*主要约束:类型参数可以指定0或者1个主要的泛型约束,主要约束可以是值类型也可以是引用类型,指定引用类型时,那么就意味着参数必须是这个引用类型或者从这个引用类型派生,还有两个特殊的主要约束:即class和struct约束,下面看一下代码:*/

internal sealed class PrimaryConstraintOfStream<T> where T : Stream ...{
public void M(T stream) ...
{
stream.Close();
// OK

}

}


PrimaryConstraintOfStream
<Stream> pcs=new PrimaryConstraintOfStream<Stream>();                          // 合法
PrimaryConstraintOfStream<FileStream> pcs=new PrimaryConstraintOfStream<FileStream>();             //合法
PrimaryConstraintOfStream<int> pcs=new PrimaryConstraintOfStream<int>();                                       //非法

//class约束

internal sealed class PrimaryConstraintOfClass<T> where T : class ...{
public void M() ...
{
T temp 
= null;                   //合法,因为已经约束了T为引用类型

}

}


//struct约束
internal sealed class PrimaryConstraintOfStruct<T> where T : struct ...{
public static T Factory() ...
{
return new
 T();
}

}
/**//*次要约束:一个类型参数可以指定0个或者多个次要约束。次要类型代表的是一个接口约束。还有一种辅助约束是类型参数之间必须存在某种关系。下面看个例子:*/

private static List<TBase> ConvertIList<T, TBase>(IList<T> list)
where T : TBase ...
{
List
<TBase> baseList = new List<TBase>
(list.Count);
for (Int32 index = 0; index < list.Count; index++) ...
{
baseList.Add(list[index]);
}

return baseList;
}


private static void CallingConvertIList() ...{
IList
<String> ls = new List<String>
();
ls.Add(
"A String"
);

IList
<Object> To = ConvertIList<String, Object>
(ls);

IList
<IComparable> lc = ConvertIList<String, IComparable>
(ls);

IList
<IComparable<String>> lcs =ConvertIList<String, IComparable<String>>
(ls);

IList
<String> ls2 = ConvertIList<String, String>
(ls);

IList
<Exception> le = ConvertIList<String, Exception>(ls);                                                    // Error,string类型和Exception没有关系

}
//构造器约束:一个指定的类型实参实现了一个public无参构造器的一个非抽象类型。如果同时指定了构造器约束和struct约束,编译器会报错,因为值类型都隐式的提供了一个无参构造器*/

internal sealed class ConstructorConstraint<T> where T : new() ...{
public static T Factory() ...
{
return new T();                               //指定了构造器约束,我们可以肯定能够返回一个T类型的实例

}

}

下面我们在看一些其他的问题:

private static void SettingAGenericTypeVariableToDefaultValue<T>() ...{
T temp 
= default(T); // OK

}


//如果我们在不指定约束的时候想初始化T类型,那么我们必须使用default关键字,这样当T是引用类型时,temp被初始化为null,如果T为值类型temp被初始化为0

还有就是一些基元操作符(/,*,+,-,等等)不能应用在泛型参数上:

private static T Sum<T>(T num) where T : struct ...{
T sum 
= default
(T) ;
for (T n = default(T); n < num; n++
)
sum 
+=
 n;
return
 sum;
}


//编译器报错
• error CS0019: Operator '<' cannot be applied to operands of type 'T' and 'T'
• error CS0023: Operator 
'++' cannot be applied to operand of type 'T'
• error CS0019: Operator 
'+=' cannot be applied to operands of type 'T' and 'T'
 
posted @ 2007-12-03 11:16  yijiangchunxue  阅读(370)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3