设为首页 加入收藏

TOP

C#语法——泛型的多种应用(一)
2018-07-31 09:13:05 】 浏览:190
Tags:语法 多种 应用

本篇文章主要介绍泛型的应用。


泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性、类型安全性和效率。


泛型的定义


下面定义了一个普通类和一个泛型类,我们可以明确看到泛型类和普通类最大的区别就是多了一个<T>。


所以,这个<T>就标记了,这个类是泛型类。其中这个T,也可以写成A,B,C,D或其他字符。


public class Generic
{
    public String Name;
}


public class Generic<T>
{
    public T Name;
}


泛型,顾名思义,就是泛指的类型。好比男人,女人,白人,黑人,可以泛称为【人】。


但类型只能是一个类型。 那么泛型和类型之间是什么关系呢?


其实很简单,泛型在定义的时候,是泛指类型;在使用的时候,就需要被指定,到底使用哪个类型。


即,使用时,就不在是泛指类型,而是特定类型。


好比,定义时,定义了一个人。但在使用时,必须明确指定,到底是黑人还是白人。


泛型的使用


泛型类跟普通类的使用方式一样,都需要实例化对象,再由对象来调用内部的属性或方法。


下面代码实例化了泛型Generic,实例化时,还指定了该泛型Generic的指定类型为String。


所以要给泛型Generic的属性Name赋值,就需要赋值字符串类型的值。


public static void Excute()
{
    Generic<String> gs = new Generic<String>();
    gs.Name = "Kiba518";
}


下面代码定义了一个Int类型的泛型Generic。


public static void Excute()
{
    Generic<int> gs = new Generic<int>();
    gs.Name = 518;
}


泛型的默认值


泛型的默认值,如下面代码所示。需要使用default(T)来赋值。


不管泛型到底是String,int,bool或者是一个Class类型,都可以被自动赋值。


public static void Excute()
{
    Generic<int> gs = new Generic<int>();
    gs.Name = 518;
    Generic<Task> gsTask = new Generic<Task>();
    gsTask.Name = new Task(()=> {
        Console.WriteLine("Kiba518");
    });
}
 
public class Generic<T>
{
    public T Name = default(T);
}


泛型的约束
在泛型类中,有个特别的约束可供我们使用。


当我们不显示的声明时,这个约束不存在。但当我们显示的声明的时候,这个约束就会执行。


下面,我们来看看这个特别的约束。


public static void Excute()
{
    Generic<FanXing> gFanXing = new Generic<FanXing>();
    Generic<Base> gFanXingBase = new Generic<Base>();
    //Generic<string> gs = new Generic<string>(); 这样定义会报错
}
public class Generic<T> where T : Base
{
    public T Name = default(T);
}
public class Base 
{
    public string Name { get; set; }
}
public class FanXing : Base
{
    public new string Name { get; set; }
}


如上面代码所示,【where T : Base】就是这个特别的约束。


当显示声明这个约束的时候,定义会限制泛型的类型。


什么是限制泛型的类型呢?


很简单,泛型T,是泛指某一个类型。我们在定义泛型类时,还需显示的指定类型,此时我们显示指定的类型,要受这个限制。


这个限制就是指【where T : Base】。


它是限制是,要求我们指定的类型T必须是Base,或者该类型继承自Base,如FanXing类。


泛型的函数


在C#中,泛型不仅可以用于类,还可以直接用于函数。


具体使用方式如下:


public static void Excute()
{
    GenericFunc gf = new GenericFunc();
    gf.FanXingFunc<FanXing>(new FanXing() { Name="Kiba518"});
}
public class GenericFunc
{
    public void FanXingFunc<T>(T obj)
    {
        Console.WriteLine(obj.GetType());
    }
}


很简单,调用泛型函数的时候,指定泛型函数的[指定类型]即可。


但是,这里我们发现一个问题,那就是,在泛型函数里,使用泛型对象的时候,我们发现对象都是object类型的。


那我们如果想使用泛型对象里的属性和方法时,要怎么办呢?


很简单,反射就可以了。


下面我们添加一个反射函数GetPropertyValue,专门用来获取属性。


public class GenericFunc
{
    public void FanXingFunc<T>(T obj)
    {
        var name = GetPropertyValue(obj, "Name");
        Console.WriteLine(name);
    }
    public object GetPropertyValue(object obj, string name)
    {
        object drv1 = obj.GetType().GetProperty(name).GetValue(obj, null);
        return drv1;
    }
}


输出结果如下:



这样我们就得到了我们想要的结果,如果想使用泛型类里的函数,道理也一样,只需要用反射来调用即可。


结语


看到这里,有些同学可能会觉得泛型很复杂,

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java并发编程之ThreadLocal内存泄.. 下一篇C#语法——await与async的正确打..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目