马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

C#语言学习:泛型(Generics) 示例代码

  [复制链接]
查看6803 | 回复7 | 2013-3-13 15:33:05 | 显示全部楼层 |阅读模式
       昨天在文章教程里面主要和大家学习了关于泛型的一些基本概念。记得第一次学习的时候感觉还是能明白泛型是什么意思,可就是到自己写的时候要么想不起来,要么就是一写就错。因此在这里,除了会展示关于泛型的一些常见用法代码之外,还会有一些错误示例,仅供大家参考。

       1. 创建泛型接口,泛型类
           在这里主要是以参考书中的一个例子作为蓝本,自己随便想到的一些东西。关于语句的注释不会太多,还请原谅。
          泛型接口
[C#] 纯文本查看 复制代码
public interface IDocument<T>
    {
        T title{get; set;}
        T content {get; set;}        
    }

泛型类
[C#] 纯文本查看 复制代码
public abstract class Document<T> : IDocument<T>
    {
        #region IDocument<string> 成员
        public T title
        {
            get;
            set;
        }
        public T content
        {
            get;
            set;
        }
        #endregion
    }

注:示例代码只是为了说明泛型的一些特点和用法,不一定满足现在的编程习惯
代码说明:首先创建了一个泛型接口,然后创建的泛型类中实现上面的接口,在这里需要指出的是,
如果是非泛型类,可以写成 Document : IDocument<string>,不能再有占位符
如果是泛型类,可以写成 Document<T> : IDocument<T>或是Document2<T, R> : IDocument<R> 或是Document<T> : IDocument<string>,而不可以写成 Document<T1> : IDocument<T2>
为了进一步说明,创建实体类
[C#] 纯文本查看 复制代码
public class NewsDocument<T> : Document<T>
    {
        public NewsDocument()
        { }

        public NewsDocument(T title, T content)
        {
            this.title = title;
            this.content = content;
        }

        public override string ToString()
        {
            return this.title + "  " + this.content;
        }
    }

NewsDocument<T>继承自抽象类 Document<T>,使用共同的占位符,根据继承的特性,同样也实现了IDocument<T>。
如果是这样定义的public class NewsDocument<T> : Document<string>,则NewsDocument就有了string类型的title和content.
例如添加一个新的类
[C#] 纯文本查看 复制代码
public class SportDocument : Document<string>
    {
        public SportDocument()
        { }

        public SportDocument(string title, string content)
        {
            this.title = title;
            this.content = content;
        }

        public override string ToString()
        {
            return this.title + "--" + this.content;
        }
    }

则SportDocument 实现了IDocument<string>接口
在使用的时候,我们分别可以这样初始化,都是没问题的
[C#] 纯文本查看 复制代码
IDocument<string> doc1 = new NewsDocument<string>("titleA", "contentA");
            IDocument<string> doc2 = new SportDocument("titleB", "contentB");

这时候再添加一个管理Document的类
[C#] 纯文本查看 复制代码
public class DocumentManager<TInput, TType> where TInput : IDocument<TType>
    {
        private List<TInput> list = new List<TInput>();

        public int AddDoc(TInput doc)
        {
            this.list.Add(doc);
            return list.Count - 1;
        }

        public TInput this[int index]
        {
            get { return this.list[index]; }
        }
    }

其实这个类我认为写成这样是最合适的public class DocumentManager<T> where T: IDocument<string>,更容易看懂一些。不过为了能够更好的演示泛型之中的这种约束关系,才写成了上面这种比较复杂的形式。不过也不难理解。首先从面相对象的角度来考虑,DocumentManager<T>中的T应该是实现了IDocument的类型,而不能是string这种简单的类型。为了能够对T有所约束,所以利用了上面说所的where。让T实现IDocument接口,但IDocument也是泛型接口,所以需要确定接口的占位符。上面说过,只能是和T一样的占位符,所以为了能够保证成立,多加了一个占位符。
使用示例:
[C#] 纯文本查看 复制代码
DocumentManager<IDocument<string>, string> manager = new DocumentManager<IDocument<string>, string>();

假如说写成DocumentManager<IDocument<string>, int> manager = new DocumentManager<IDocument<string>, int>();
这时编译器就会提示出现错误。
      2. 泛型方法
          在之前的帖子里面写过一些泛型方法,只列举其中的一个
[C#] 纯文本查看 复制代码
public static T[] Select_Sort<T>(T[] originArray) where T : IComparable<T>
        {
            if (originArray.Length == 0 || originArray.Length == 1)
            {
                return originArray;
            }

            for (int i = 0; i < originArray.Length; i++)
            {
                for (int j = i + 1; j < originArray.Length; j++)
                {
                    if (originArray[i].CompareTo(originArray[j]) == 1)
                    {
                        T temp = originArray[i];
                        originArray[i] = originArray[j];
                        originArray[j] = temp;
                    }
                }
            }

            return originArray;
        }

之前帖子的示例使用的是泛型委托,在这里换成了T实现IComparable<T>接口来比较。说明一点,如果不使用接口约束或是委托,是会报错的,因为泛型还没有实现对运算符的约束。在调用的时候,因为能够从参数进行推算,所以方法后面可以不用带占位符。比如 Sort(int[] ...)和 Sort<int>(int[] ...)是一样的
IoveBC | 2013-3-13 17:04:27 | 显示全部楼层
泛型主要是用来干嘛的啊?。。。我们还没有开始学习这个泛型勒
IoveBC | 2013-3-18 23:44:37 | 显示全部楼层
没人回答么,,,(顺便冲上600分!)
hebutyll | 2013-3-19 08:45:44 | 显示全部楼层
IoveBC 发表于 2013-3-18 23:44
没人回答么,,,(顺便冲上600分!)

泛型对于编程的意义很大,你可以在网上搜一下关于泛型的介绍
IoveBC | 2013-4-2 21:58:12 | 显示全部楼层
哦,现在开始了解一些泛型方面的知识了
chao2332601 | 2013-6-16 01:33:30 | 显示全部楼层
谢谢分享!!!
chao2332601 | 2013-6-16 05:05:44 | 显示全部楼层
谢谢分享!!!
ssy340 | 2013-8-25 21:37:05 | 显示全部楼层
泛型这东西作用大,用好比较难
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则