C#-泛型

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TestMyGeneric;

//泛型类
public class MyGeneric<T> : IMyGeneric<string>
{
    public T _T;

    public string GetT(string t)
    {
        return t;
    }
}

//子类继承泛型父类,必须指定具体类型,如果子类也是泛型,则不用指定
public class MyGenericSubClass : MyGeneric<int>
{

}

//泛型接口
public interface IMyGeneric<T>
{
    T GetT(T t);
}

//泛型接口也是一样,必须指定具体类型,如果子类也是泛型,则不用指定
public interface IMyGenericSub : IMyGeneric<double>
{

}

//泛型委托
public delegate T OnPrint<T>(T t);

public struct StructDemo
{
    public int Id { get; set; }
    public string Name { get; set; }
}

namespace TestMyGeneric
{
    public interface ISports
    {
        void Pingpang();
    }

    public interface IWork
    {
        void Work();
    }

    public class People
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public void Hi()
        {
           Debug.Log("Hi");
        }
    }

    public class Chinese : People, ISports, IWork
    {
        public void Tradition()
        {
             Debug.Log("good good good!!");
        }
        public void SayHi()
        {
             Debug.Log("nin chi le me?");
        }

        public void Pingpang()
        {
            Debug.Log("Play Pingpang...");
        }

        public void Work()
        {
            Debug.Log("Work Hard...");
        }
    }

    public class Hubei : Chinese
    {
        public Hubei(int version)
        { }

        public string Changjiang { get; set; }
        public void Majiang()
        {
            Debug.Log("Play Majiang...");
        }
    }

    public class Japanese : ISports
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public void Hi()
        {
             Debug.Log("Hi");
        }
        public void Pingpang()
        {
            Debug.Log("Play Pingpang...");
        }
    }
}

public class TestGeneric : MonoBehaviour
{

	// Use this for initialization
	void Start () {

        ShowMyData("lalala");
        ShowMyData(5);
        ShowMyData(6.66);

        MyGeneric<string> g1 = new MyGeneric<string>();
        g1._T = "hello";

        MyGeneric<int> g2 = new MyGeneric<int>();
        g2._T = 123;

        Debug.Log(g1.GetT(g1._T));
        Debug.Log(g2.GetT(g2._T.ToString()));

        MyGenericSubClass s1 = new MyGenericSubClass();
        s1._T = 456;
        Debug.Log(s1.GetT(s1._T.ToString()));

        TestFunc();

        //泛型代理
        OnPrint<string> myPrint = new OnPrint<string>(GetMyPrint);
        myPrint.Invoke("myPrint~~~");

        OnPrint<int> myPrintInt = new OnPrint<int>(GetMyPrint);
        myPrintInt.Invoke(5);

        OnMyPrint<string>(GetMyPrint, "111");
        OnMyPrint<int>(GetMyPrint, 222);
	}
	
    public void OnMyPrint<T>(OnPrint<T> t, T v)
    {
        t(v);
    }

    public T GetMyPrint<T>(T t)
    {
        Debug.Log(t);
        return t;
    }

    //泛型方法
    private void ShowMyData<T>(T t)
    {
        Debug.Log("type = " + t.GetType().ToString() + " value = " + t.ToString());
    }

    public void TestFunc()
    {
        People people = new People()
        {
            Id = 123,
            Name = "People"
        };
        Chinese chinese = new Chinese()
        {
            Id = 234,
            Name = "Chinese"
        };
        Hubei hubei = new Hubei(123)
        {
            Id = 345,
            Name = "Hubei"
        };
        Japanese japanese = new Japanese()
        {
            Id = 7654,
            Name = "Japanese"
        };

        ShowObject(people);
        ShowObject(chinese);
        ShowObject(hubei);
        //ShowObject(japanese);

        Show(chinese);

        var obj1 = GenericToDefault<string>();
        var obj2 = GenericToDefault<int>();
        var obj3 = GenericToDefault<StructDemo>();
    }

    /// <summary>
    /// 基类约束:约束T必须是People类型或者是People的子类
    /// 基类约束时,基类不能是密封类,即不能是sealed类。sealed类表示该类不能被继承,在这里用作约束就无任何意义,因为sealed类没有子类。
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="oParameter"></param>

    private void ShowObject<T>(T oParameter) where T : People
    {
        Debug.Log(oParameter.GetType().Name + " " + oParameter.Id + " " + oParameter.Name);
    }

    /// <summary>
    /// 接口约束
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public T GetTSports<T>(T t) where T : ISports
    {   
        t.Pingpang();
        return t;
    }

    /// <summary>
    /// 引用类型约束
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public T GetTClass<T>(T t) where T : class
    {
        return t;
    }

    /// <summary>
    /// 值类型类型约束
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public T GetTStruct<T>(T t) where T : struct
    {
        return t;
    }

    /// <summary>
    /// 无参数构造函数约束  new()
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="t"></param>
    /// <returns></returns>
    public T GetTNew<T>(T t) where T : new()
    {
        return t;
    }

    //注意:有多个泛型约束时,new()约束一定是在最后。
    public void Show<T>(T tParameter) where T : People, ISports, IWork, new()
    {
        Debug.Log(tParameter.Id + tParameter.Name);
        tParameter.Hi();
        tParameter.Pingpang();
        tParameter.Work();
    }

    //给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t = null 才有效;
    //只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。
    //解决方案是使用 default 关键字,此关键字对于引用类型会返回空,对于数值类型会返回零。
    //对于结构,此关键字将返回初始化为零或空的每个结构成员,具体取决于这些结构是值类型还是引用类型。
    /// <summary>
    /// 泛型代码中的默认关键字:Default
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static T GenericToDefault<T>()
    {
        return default(T);
    }

	// Update is called once per frame
	void Update () {
		
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值