C#泛型
/*
泛型:
泛型类:访问修饰符class类名<泛型修饰符>
{
泛型方法
访问修饰符 返回值类型 方法名(参数类型) { }
}
泛型类:
<T>:为类型占位
泛型的变量不能使用运算符'+'
泛型成员因类型不确定,可能是类、结构体、字符、枚举……所以不能使用算术运算符、比较运算符等进行运算!
注意!可以使用赋值运算符。
*/
public class SwapNum<T>
{
public void swap(T a, T b)
{
T temp = a;
a = b;
b = temp;
Console.WriteLine("交换两个值\na为:{0}\nb为:{1}",a,b);
}
}
public class SwapNum2<E, C, T> {
public void text(E a,C b,T c) {
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
}
}
/*
泛型约束
where T:class------>参数类型必须是引用类型
where T:struct----->参数类型必须是值类型
where T:<父类名>--->参数类型必须是指定的父类
where T:<接口名>--->参数类型必须是指定的接口,多个接口可以使用‘,’隔开
*/
//泛型参数约束
//值类型
public class Test<T> where T : struct//指定了参数必须为值类型的
{
public void test(T t)
{
Console.WriteLine("T的值为:{0}", t);
}
}
/*
泛型类继承
1.泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类;
2.父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;
*/
public class Test2<T,S>
{
public void test(T t)
{
Console.WriteLine("T的值为:{0}", t);
}
}
//如果这样写的话,显然会报找不到类型T,S的错误
public class TestChild : Test2<T, S> { }
//正确的写法应该是
public class TestChild1 : Test2<string, int> { }
public class TestChild<T, S> : Test2<T, S> { }
public class TestChild1<T, S> : Test2<String, int> { }
/*泛型接口
其创建以及继承规则和上面说的泛型类是一样的
*/
public interface IList<T>
{
T[] GetElements();
}
public interface IDictionary<K, V>
{
void Add(K key, V value);
}
// 泛型接口的类型参数要么已实例化
// 要么来源于实现类声明的类型参数
class List<T> : IList<T>, IDictionary<int, T>
{
public T[] GetElements() { return null; }
public void Add(int index, T value)
{ }
}
/*
泛型委托
首先我们定义一个类型参数为T的委托,然后在类中利用委托调用方法
*/
//定义一个委托,类型参数为T,返回值类型T
//泛型委托支持在返回值和参数上应用类型参数
delegate string GenericDelete<T>(T value);
class test
{
static string F(int i) { return "SHY520"; }
static string G(string s) { return "SHY520"; }
static void Main(string[] args)
{
GenericDelete<string> G1 = G;
GenericDelete<int> G2 = new GenericDelete<int>(F);
}
}
/*泛型方法
C#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。
特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,
但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。
还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。
下面我们分别看一下泛型类型的申明,调用,重载和覆盖。
*/
class GenericClass
{
//申明一个泛型方法
public T getvalue<T>(T t)
{
return t;
}
//调用泛型方法
//注意:在调用泛型方法时,对泛型方法的类型参数实例化
public int useMethod()
{
return this.getvalue<int>(10);
}
//重载getvalue方法
public int getvalue(int i)
{
return i;
}
}
//下面演示覆盖
//要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系
abstract class Parent
{
public abstract K TEST<K, V>(K k, V v) where K : V;
}
class Child : Parent
{
public override T TEST<T, S>(T t, S s)
{
return t;
}
}
//1、基类约束:
class A { public void F1() { } }
class B { public void F2() { } }
class C<S, T>
where S : A // S继承自A
where T : B // T继承自B
{
// 可以在类型为S的变量上调用F1,
// 可以在类型为T的变量上调用F2
}
//2、接口约束
interface IPrintable { void Print(); }
interface IComparable<T> { int CompareTo(T v); }
interface IKeyProvider<T> { T GetKey(); }
class Dictionary<K, V>
where K : IComparable<K>
where V : IPrintable, IKeyProvider<K>
{
// 可以在类型为K的变量上调用CompareTo,
// 可以在类型为V的变量上调用Print和GetKey
}
//3、构造器约束
class A { public A() { } }
class B { public B(int i) { } }
class C<T>
where T : new()
{
//可以在其中使用T t=new T();
}
C<A> c = new C<A>(); //可以,A有无参构造器
C<B> c = new C<B>(); //错误,B没有无参构造器
//4、值/引用类型约束
public struct A { }
public class B { }
class C<T>
where T : struct
{
// T在这里面是一个值类型
}
C<A> c = new C<A>(); //可以,A是一个值类型
C<B> c = new C<B>(); //错误,B是一个引用类型
因为经历,
所以懂得;
因为懂得,
所以珍惜。

浙公网安备 33010602011771号