c#----泛型(一)

一、泛型

  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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值