C#:泛型类

对于泛型类,我们一定十分熟悉了。比如:List,Dictionary<T1,T2>等等。

泛型类型的声明,在C#:泛型中已经提及,下面给出一些示例;

泛型单例:它是一种泛型类型;类型参数(如:T)用来代替需要支持单例模式的类型;提供一个公开的、返回值类型为T、的静态方法。

class SingleTonBase<T> where T : class
{
    private static T _instance;
    public static readonly object SyncObject = new object();
    public static T GetInstance()
    {
        if (_instance == null)//为了防止每次都要获取锁,增加程序耗时
        {
            lock (SyncObject)//同步锁,防止实例被同时访问
            {
                if (_instance == null)
                {
                    _instance = (T) Activator.CreateInstance(typeof(T), true);
                }
            }
        }
        return _instance;
    }
    public static void SetInstance(T value)
    {
        _instance = value;
    } 
}

使用方式:

class Program
{
    static void Main(string[] args)
    {
        for (int i = 0; i < 10; i++)
        {
            Thread thread=new Thread(new ThreadStart(TestSingleton));
            thread.Start();
        }
        Console.ReadLine();
    }
    static void TestSingleton()
    {
        Student student = SingleTonBase<Student>.GetInstance();
        Console.WriteLine($"{student.GetHashCode()}:{student.StudentName},{student.StudentAge}");
    }
}
class Student
{
    private  Student()
    {
        StudentName = "admin";
        StudentAge = 18;
        Console.WriteLine("构造函数运行...");
    }
    public string StudentName { get; set; }
    public int StudentAge { get; set; }
}

运行结果:

构造函数运行...
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18
12036987:admin,18

通过运行结果可以看出:通过泛型类型SingleTonBase提供的GetInstance()方法,我们能够保证在任何时候操作的都是同一个Student类型对象。

为泛型类型提供扩展方法

class Program
{
    static void Main(string[] args)
    {
        List<Student> list = new List<Student>()
        {
            new Student() {StudentName = "唐三", StudentClass = "史莱克七怪", StudentAge = 17},
            new Student() {StudentName = "小舞", StudentClass = "史莱克七怪", StudentAge = 16},
            new Student() {StudentName = "朱竹青", StudentClass = "史莱克七怪", StudentAge = 16},
            new Student() {StudentName = "胡列娜", StudentClass = "武魂殿", StudentAge = 19}
        };
        list.PrintItems();
        Console.ReadLine();
    }
}
public class Student
{
    public string StudentName { get; set; }
    public string StudentClass { get; set; }
    public int StudentAge { get; set; }
    public override string ToString()
    {
        return $"{StudentClass},{StudentName},{StudentAge}";
    }
}
public static class ExtendList
{
    public static void PrintItems<T>(this List<T> list)
    {
        list?.ForEach(x=>{ Console.WriteLine(x.ToString()); });
    }
}

运行结果:

史莱克七怪,唐三,17
史莱克七怪,小舞,16
史莱克七怪,朱竹青,16
武魂殿,胡列娜,19

需要注意:PrintItems()被声明成了泛型的扩展方法:是因为我们是对泛型类型进行扩展的;如果方法参数类型是List,就不需要将扩展方法声明称泛型方法了;但这样写的话,就不是为泛型类型提供扩展方法了。

不要滥用扩展方法

class Program
{
    static void Main(string[] args)
    {
        object o=new object();
        o.ExtendEveryThing();
        13.ExtendEveryThing();
        "hah".ExtendEveryThing();
        new List<int>().ExtendEveryThing();
        Console.ReadLine();
    }
}
public static class ExtendAll
{
    //对T类型 提供了扩展方法,会让所有类型都被污染到
    public static void ExtendEveryThing<T>(this T ss)
    {
    }
}

数据类型被用作类型实参后,他们的构造类型不再具有继承关系。

class Shape
{
    public double Width { get; set; }
    public double Height { get; set; }
    public virtual double CaculatorArea()
    {
        return Width * Height;
    }
}
class Rectangle:Shape
{
}
class Triangle:Shape
{
    public override double CaculatorArea()
    {
        return Width * Height / 2;
    }
}


List< Shape >类型和List< Rectangle >类型就是两种新的用户定义的类型,所以他们之间没有任何关系,类型转换自然不会成功。

以上便是对泛型类型的知识总结,记录下来以便以后查看。

posted @ 2020-11-22 20:43  BigBosscyb  阅读(806)  评论(0编辑  收藏  举报