泛型(generic),简单的说就是使用相同的代码操作不同的数据类型,简化代码的编写工作;相关的概念包括泛型方法、泛型类、泛型接口、泛型约束等。

泛型方法

关于泛型方法,我比较喜欢的例子就是交换两个变量的值。先看一个交换int类型数据的方法,如下面的代码。

using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 99;
            Swap(ref a, ref b);
            Console.WriteLine("a={0}, b={1}", a, b);
        }
        //
        static void Swap(ref int x,ref int y)
        {
            int tmp = x;
            x = y;
            y = tmp;
        }
    }
}

代码执行结果如下图所示。

enter image description here

交换两个数据的操作是很常见的操作,如果需要对每个类型都写一个重载方法,那工作量就太大了,而泛型就是来解决这类问题的;下面的代码,我们使用一个泛型方法来解决两个值交换的问题。

using System;

namespace ConsoleTest
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 10;
            int b = 99;
            Swap(ref a, ref b);
            Console.WriteLine("a={0}, b={1}", a, b);
        }
        //
        static void Swap<T>(ref T x,ref T y)
        {
            T tmp = x;
            x = y;
            y = tmp;
        }
    }
}

代码执行结果与上图一致,关键在于,使用这里的Swap()方法可以交换任何类型的数据,而不只是int类型,大家可定义不同类型的数据进行测试。

此处定义的Swap()方法就是一个泛型方法,与普通方法的不同之处在于,方法名的后面使用一对尖括号声明了一个类型标识符T(type),这是一个习惯用法,实际应用中还可以声明多个类型标识;定义了类型标识之后,就可以在方法的参数、方法体和返回值中使用,如下面的代码。

static T Test<T>(T x)
{
        T y = x;
        return y;
}

泛型类

定义泛型类时,需要在类名后面使用一对尖括号声明类型标识,然后,在类中就可以使用这些类型标识了,如下面的代码。

namespace ConsoleTest
{
    public class CDictItem<K,V>
    {
        public K Key { get; set; }
        public V Value { get; set; }
    }
}

本例中,我们定义了CDictItem类,并定义了两个类型标识,K和V,分别表示字典项目的键(key)和值(value);下面的代码演示了如何使用这个泛型类。

static void Main(string[] args)
{
        CDictItem<string, string> item = new CDictItem<string, string>();
        item.Key = "Mars";
        item.Value = "火星";
        Console.WriteLine("{0}: {1}", item.Key, item.Value);
}

代码执行结果如下图所示。

enter image description here

泛型接口

接口的功能就是定义算法和功能标准,使用了泛型就可以通过一个接口完成更多数据类型的相同操作。需要注意的是,实现泛型接口时应使用泛型类,如下面的代码演示了一个简单的泛型接口实现。

//
public interface  IG1<T>
{
    T Data { get; set; }
    void ShowData(T d);
}
//
public class CG1<T> : IG1<T>
{
    public T Data { get; set; }
    public void ShowData(T d)
    {
        Console.WriteLine(d == null ? "NULL" : d.ToString());
    }
}

泛型约束

泛型约束是指,在使用泛型类型时,其数据类型可以进行限制,如操作的数据类型必须是实现了某接口的类型,如下面的代码。

public class CCls1<T> where T : I1
{
    public T Obj { get; set; }
}

这里的CCls1类中的T类型必须是实现了I1接口的类型。

小结

从以上内容中可以看到,泛型就是定义一个算法或功能,在真正使用时才指定具体的数据类型,这样的好处就是提高开发效率,而且,由于代码执行时会绑定具体的类型,所以也不会影响执行效率;这样一来,泛型的强大之处就一目了然了。

在.NET Framework类库中定义了大量的泛型资源,在学习和工作中可以参考MSDN文档使用。

CHY软件小屋原创作品!