最显著点就是它参数化了类型把类型作为参数抽象出来从而使我们在实际运用当中能够更好实现代码重复利用同时它提供了更强类型安全更高效率不过在约束方面它只支持显示约束这样在灵活性方面就显得不是那么好了我觉得它的所以能够提供更高效率是泛型在例子化时候采用了"on-demand"模式,即按需例子化,发生在JIT(Just In Time)编译时
下面来看如何定义个泛型类很简单你只需要意识到点,在这里,类型已经被参数化了:
using ;
using .Collections.Generic;
using .Text;
GenericTest
{
Program
{
void Main( args)
{
//使用,来例子化Test<T,S>类
Test<, > t = Test<, >("SHY520",22);
//泛型类中思路方法
t.SetValue;
}
}
/**//// <summary>
/// 定义个泛型类该类有两个类型参数分别是T,S
/// http://pw.cnblogs.com
/// </summary>
/// <typeparam name="T">类型参数</typeparam>
/// <typeparam name="S">类型参数</typeparam>
public Test<T,S>
{
//泛型类类型参数可用于类成员
private T name;
private S age;
public Test(T Name,S Age)
{
this.name = Name;
this.age = Age;
}
public void SetValue
{
Console.WriteLine(name.);
Console.WriteLine(age.);
}
}
}
上面例子不是很恰当目是让初学泛型你了解下泛型定义及例子化思路方法如上我们定义了个泛型类那么如何实现泛型类继承呢?这里需要满足下面两点中任何点即可:
1、泛型类继承中父类类型参数已被例子化这种情况下子类不定必须是泛型类;
2、父类类型参数没有被例子化但来源于子类也就是说父类和子类都是泛型类并且 2者有相同类型参数;
//如果这样写话显然会报找不到类型T,S
public TestChild : Test<T, S> { }
//正确写法应该是
public TestChild : Test<, >{ }
public TestChild<T, S> : Test<T, S> { }
public TestChild<T, S> : Test<String, > { }
接着我们来看看泛型接口其创建以及继承规则和上面说泛型类是样看下面代码:
public erface IList<T>
{
T GetElements;
}
public erface IDictionary<K,V>
{
void Add(K key, V value);
}
// 泛型接口类型参数要么已例子化
// 要么来源于实现类声明类型参数
List<T> : IList<T>, IDictionary<, T>
{
public T GetElements { null; }
public void Add( index, T value)
{}
}
在来看下泛型委托首先我们定义个类型参数为T委托然后在类中利用委托思路方法:
using ;
using .Collections.Generic;
using .Text;
GenericTest
{
//定义个委托类型参数为T返回值类型T
//泛型委托支持在返回值和参数上应用类型参数
delegate GenericDelete<T>(T value);
test
{
F( i) { "SHY520"; }
G( s) { "SHY520"; }
void Main( args)
{
GenericDelete<> G1 = G;
GenericDelete<> G2 = GenericDelete<>(F);
}
}
}
我们再来看泛型思路方法C#泛型机制只支持在思路方法申明上包含类型参数也即是泛型思路方法特别注意是泛型不支持在除了思路方法以外其他类/接口成员上使用类型参数但这些成员可以被包含在泛型类型中并且可以使用泛型类型类型参数还有点需要说就是泛型思路方法可以在泛型类型中也可以存在于非泛型类型中下面我们分别看下泛型类型申明重载和覆盖
using ;
using .Collections.Generic;
using .Text;
GenericTest
{
GenericClass
{
//申明个泛型思路方法
public T getvalue<T>(T t)
{
t;
}
//泛型思路方法
//注意:在泛型思路方法时对泛型思路方法类型参数例子化
public useMethod
{
this.getvalue<>(10);
}
//重载getvalue思路方法
public getvalue( i)
{
i;
}
}
//下面演示覆盖
//要注意是泛型思路方法被覆盖时约束被默认继承不需要重新指定约束关系
abstract Parent
{
public abstract K TEST<K, V>(K k, V v) where K : V;
}
Child : Parent
{
public override T TEST<T, S>(T t, S s)
{
t;
}
}
}
最后我们来看下泛型中约束:
C#中泛型只支持显示约束这样才能保证C#所要求类型安全但显示约束并非时必须如果不加约束泛型类型参数将只能访问.Object类型中公有思路方法“显式约束”由where子句表达可以指定“基类约束”“接口约束”“构造器约束”“值类型/引用类型约束”共 4种约束下面例子来源于李建忠老师讲座PPT
1、基类约束:
A { public void F1 {} }
B { public void F2 {} }
C<S,T>
where S: A // S继承自A
where T: B // T继承自B
{
// 可以在类型为S变量上F1
// 可以在类型为T变量上F2
}
2、接口约束
erface IPrable { void Pr; }
erface IComparable<T> { CompareTo(T v);}
erface IKeyProvider<T> { T GetKey; }
Dictionary<K,V>
where K: IComparable<K>
where V: IPrable, IKeyProvider<K>
{
// 可以在类型为K变量上CompareTo
// 可以在类型为V变量上Pr和GetKey
}
3、构造器约束
A { public A { } }
B { public B( i) { } }
C<T>
where T :
{
//可以在其中使用T t= T;
}
C<A> c= C<A>; //可以A有无参构造器
C<B> c= C<B>; //B没有无参构造器
4、值/引用类型约束
public struct A { }
public B { }
C<T>
where T : struct
{
// T在这里面是个值类型
}
C<A> c= C<A>; //可以A是个值类型
C<B> c= C<B>; //B是个引用类型
最新评论