c#----泛型(一)

来源:互联网 发布:在线网络理财产品排名 编辑:程序博客网 时间:2024/04/30 18:14

一、泛型

  class Program    {        static void Main(string[] args)        {            Aint a = new Aint(2);            Console.WriteLine(a.Num);            Bstring b = new Bstring("a");            Console.WriteLine(b.Str);            Console.Read();        }    }    public class Aint    {        private int num;        public int Num { get { return num; } }        public Aint(int i)        {            num = i;        }    }    public class Bstring    {        private string str;        public string Str { get { return str; } }        public Bstring(string i)        {            str = i;        }    }

当两个模块的功能非常相似,却类型不同如果想要合并代码怎么办?

可以把类型改为object

    public class Cobject    {        private object ob;        public object Ob { get { return ob; } }        public Cobject(object i)        {            ob = i;        }    }

虽然减少了代码量,但object不是类型安全的,而且会进行封箱拆箱。

所以泛型的作用:可以创建独立于被包含类型的类和方法。我们不必给不同的类型编写功能相同的许多方法或类,只创建一个方法或类即可。

       static void Main(string[] args)        {            Example<string> a = new Example<string>("a");            System.Console.WriteLine(a.Ex);            Console.Read();        }    public class Example<T>    {        private T ex;        public T Ex { get { return ex; } }        public Example(T i)        {            ex = i;        }    }

通用类型T只是一个占位符,在实例化类时,根据用户指定的数据类型代替T并由即时编译器(JIT)生成本地代码,这个本地代码中已经使用了实际的数据类型,等同于用实际类型写的类,所以不同的封闭类的本地代码是不一样的。
      所以可以认为:Example<string> a 和 Example<int> b是不同的类

他的优点显而易见:

1.       他是类型安全的。实例化了int类型的栈,就不能处理string类型的数据,其他数据类型也一样。

2.       无需装箱和折箱。这个类在实例化时,按照所传入的数据类型生成本地代码,本地代码数据类型已确定,所以无需装箱和拆箱。

 

二、默认值

    public class Example<T>    {        public void Show(T str)        {            T  a =default(T);            if (str != null)                a = str;        }    }

因为不知道是值类型,还是引用类型,所以不能给泛型赋值null或者0,要用default来设置,如果T是值类型则赋值null,反之0

三、泛型约束

 现在有一个接口:

  interface IName    {        string Name { get; set; }    }

如果想让泛型类来显示名字(Name):可以将T转换为IName来显示,但是如果T类型没有实现接口IName就会异常,所以需要给T规定:必须实现IName接口

    class Ducument<T>     {        public void Show(T doc)        {            Console.WriteLine(((IName)doc).Name);        }    }

则:

class Ducument<T> where T:IName

如此可以这样写:

 class Ducument<T> where T:IName    {        public void Show(IName doc)        {            Console.WriteLine(doc.Name);        }    }

最后:   People类如果没有实现IName接口就会提示错误

 class Program    {        static void Main(string[] args)        {            People a = new People("VenVertu");            Ducument<People> p = new Ducument<People>();            p.Show(a);            Console.Read();        }    }    interface IName    {        string Name { get; set; }    }    class People : IName    {        public string Name { get; set; }        public People(string name)        {            this.Name = name;        }    }    class Ducument<T> where T:IName    {        public void Show(IName doc)        {            Console.WriteLine("我叫 :"+doc.Name);        }    }

1.必须为值类型 T:class.   2.必须为引用类型 T:struct     3.必须有个无参构造函数 T:new()

    继承一样可以有多个接口约束,只能有一个类约束,每个约束用逗号隔开。new()必须在最后一个。

 

四、泛型中的静态成员变量

class Program    {        static void Main(string[] args)        {            StaticDemo<int> a = new StaticDemo<int>();            StaticDemo<int> b = new StaticDemo<int>();            StaticDemo<string> str = new StaticDemo<string>();            Console.WriteLine(StaticDemo<int>.Count);            Console.WriteLine(StaticDemo<string>.Count);            Console.Read();        }    }    class StaticDemo<T>    {        public static int Count { get; set; }         public  StaticDemo()        {            Count++;        }    }

结果是 输出2      和  1      :所以StaticDemo<int>和StaticDemo<string>是两个不同的类型

 

 

                                          


                                    =========在所有弱点中,最大弱点就是暴露弱点===========


 

0 0