C#泛型简介和使用

1.泛型简介:通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用。在.NET类库中处处都可以看到泛型的身影,尤其是数组和集合中,泛型的存在也大大提高了程序员的开发效率。更重要的是,C#的泛型比C++的模板使用更加安全,并且通过避免装箱和拆箱操作来达到性能提升的目的。因此,我们很有必要掌握并善用这个强大的语言特性。 比较类似与C++的模板)。泛型在编译时提供强大的类型检查,减少数据类型之间的显示转换、装箱操作和运行时的类型检查。

泛型的作用:用于处理算法、数据结构的一种编程方法。泛型通常用在集合和在集合上运行的方法中。泛型主要是提高了代码的重用性。

(1).性能:值类型存储在栈上,引用类型存储在堆上。C#类是引用类型,结构是值类型。将值类型转换为引用类型称为装箱。使用泛型可以不用装箱和拆箱。

(2).类型安全(3).二进制代码的重用(4)代码的扩展

2泛型的应用:

2.1.创建泛型类:定义与一般的类比较类似,只是又要使用泛型类型声明,之后可以作为一个字段成员,或者方法的参数类型。

类型参数T :类似一个占位符,表示某种可能的类型。

2.1泛型类的功能:在创建泛型类的时候,还需要其它的C#的关键字。

创建一个泛型的文档管理器


    public class DocumentManager<T> {
        private readonly Queue<T> DocumentQueue = new Queue<T>();
        public void AddDocument(T doc) { 
        lock (this){
            DocumentQueue.Equals(doc);
        }
        }
        public bool IsDocumentAvailable {
            get { return DocumentQueue.Count()>0; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
        }
    }

2.1.1默认值

给DocumentManager<T>类添加一个GetDocument()方法。通过default关键字,将null赋予引用类型,将0赋予值类型。

public T GetDocument() {

        T doc=default (T);

        lock (this)

        {

            DocumentQueue.Equals(doc);

        }

        return doc;

        }

2.1.2约束:如果泛型类需要调用泛型类型中的方法,就必须添加约束。对于DocumentManager<T>,文档的所有标题应在DispalyAllDocument()方法中显示,Document类实现了带有Title和Content属性的IDocument接口。

public interface IDocument

    {

        string Title { get; set; }

        string Content { get; set; }

    }



    public class Document : IDocument

    {

        public Document()

        {

        }



        public Document(string title, string content)

        {

            this.Title = title;

            this.Content = content;

        }



        public string Title { get; set; }

        public string Content { get; set; }

    }

 

要使用DocumentManager<T>类显示文档,可以将类型T强制转换为IDocument接口,以显示标题。

public void DisplayAllDocuments()

        {

            foreach (TDocument doc in documentQueue)

            {

                Console.WriteLine(doc.Title);

            }

        }

重新定义类DocumentManager

public class DocumentManager<TDocument>

        where TDocument : IDocument//约束条件

    {

泛型支持几种约束类型,使用泛型约束还可以合并多个约束。

2.1.3继承

泛型类型可以实现泛型接口,也可以派生自一个类,泛型类可以派生自泛型基类;要求是必须重复接口的泛型类型,或者必须指定基类的类型,于是派生类可以是泛型或者非泛型类。

2.1.4静态成员

泛型类的静态成员需要特别关注。泛型类的静态成员只能在类的一个实例中共享。

3.泛型接口:使用泛型可以定义接口,在接口定义的方法可以带泛型参数。

*3.1泛型接口的协变和抗变

3.2泛型接口的协变

如果泛型类型用out关键字标注,泛型接口就是协变。返回类型只能是T。

3.3泛型接口的抗变

如果泛型类型用in关键字标注,泛型接口就是抗变。接口只能把泛型类型T用作其方法的输入。

*4泛型结构

与类相似,结构也可以是泛型的。他们分厂类似于泛型类,只是没有继承特性。

5泛型方法

泛型方法可以在非泛型类中定义。

5.1方法示例:泛型方法累加集合中所有的元素。

public class Account

    {

        public string Name { get; private set; }

        public decimal Balance { get; private set; }



        public Account(string name, Decimal balance)

        {

            this.Name = name;

            this.Balance = balance;

        }

    }

其中应累加余额的所有账户操作都添加到List<Account>类型的账户列表中。

var accounts = new List<Account>()

            {

                new Account("Christian", 1500),

                new Account("Stephanie", 2200),

                new Account("Angela", 1800)

            };

累加Account的方法:

public static decimal AccumulateSimple(IEnumerable<Account> source)

        {

            decimal sum = 0;

            foreach (Account a in source)

            {

                sum += a.Balance;

            }

            return sum;

        }

5.2 带约束的泛型方法

public static decimal Accumulate<TAccount>(IEnumerable<TAccount> source)

            where TAccount : IAccount

        {

            decimal sum = 0;



            foreach (TAccount a in source)

            {

                sum += a.Balance;

            }

            return sum;

        }

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页