admin管理员组

文章数量:1032705

C#.net 泛型学习

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    class Program

    {

        static void Main(string[] args)

        {

            //使用string,int来实例化Test<T,S>类

            Test<string, int> t = new Test<string, int>('SHY520',22);

            //调用泛型类中的方法

            t.SetValue();

        }

    }

    /**//// <summary>

    /// 定义一个泛型类,该类有两个类型参数,分别是T,S

    /// 

    /// </summary>

    /// <typeparam name='T'>类型参数</typeparam>

    /// <typeparam name='S'>类型参数</typeparam>

    public class 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.ToString());

            Console.WriteLine(age.ToString());

        }

    }

}

        上面的例子不是很恰当,目的是让初学泛型的你了解一下泛型的定义及实例化方法,如上,我们定义了一个泛型类,那么如何实现泛型类的继承呢?这里需要满足下面两点中的任何一点即可: 1、泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类; 2、父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;

    //如果这样写的话,显然会报找不到类型T,S的错误

    public class TestChild : Test<T, S> { }

    //正确的写法应该是

    public class TestChild : Test<string, int>{ }

    public class TestChild<T, S> : Test<T, S> { }

    public class TestChild<T, S> : Test<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的委托,然后在类中利用委托调用方法:

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    //定义一个委托,类型参数为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#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    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;

        }

    }

}

        最后我们来看一下泛型中的约束:         C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。 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是一个引用类型

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2012-03-20,如有侵权请联系 cloudcommunity@tencent 删除继承接口c#变量泛型

C#.net 泛型学习

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    class Program

    {

        static void Main(string[] args)

        {

            //使用string,int来实例化Test<T,S>类

            Test<string, int> t = new Test<string, int>('SHY520',22);

            //调用泛型类中的方法

            t.SetValue();

        }

    }

    /**//// <summary>

    /// 定义一个泛型类,该类有两个类型参数,分别是T,S

    /// 

    /// </summary>

    /// <typeparam name='T'>类型参数</typeparam>

    /// <typeparam name='S'>类型参数</typeparam>

    public class 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.ToString());

            Console.WriteLine(age.ToString());

        }

    }

}

        上面的例子不是很恰当,目的是让初学泛型的你了解一下泛型的定义及实例化方法,如上,我们定义了一个泛型类,那么如何实现泛型类的继承呢?这里需要满足下面两点中的任何一点即可: 1、泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类; 2、父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;

    //如果这样写的话,显然会报找不到类型T,S的错误

    public class TestChild : Test<T, S> { }

    //正确的写法应该是

    public class TestChild : Test<string, int>{ }

    public class TestChild<T, S> : Test<T, S> { }

    public class TestChild<T, S> : Test<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的委托,然后在类中利用委托调用方法:

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    //定义一个委托,类型参数为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#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。

using System;

using System.Collections.Generic;

using System.Text;

namespace GenericTest

{

    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;

        }

    }

}

        最后我们来看一下泛型中的约束:         C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。 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是一个引用类型

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2012-03-20,如有侵权请联系 cloudcommunity@tencent 删除继承接口c#变量泛型

本文标签: Cnet 泛型学习