//简易的泛型方法
//泛型使程序员能够为类型定义和方法参数定义“占位符”(正式名称为类型参数),类型参数等到创建泛型类型活调用泛型方法时再指定
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace SimpleGeneric
{
    //创建泛型方法
    public class MyHelperClass
    {
        public static void Swap<T>(ref T a, ref T b)
        {
            Console.WriteLine("you sent the swap() method a {0}", typeof(T));
            T temp;
            temp = a;
            a = b;
            b = temp;
        }
 
        public static void DisplayBaseClass<T>()
        {
            Console.WriteLine("Base class of {0} is :{1}", typeof(T), typeof(T).BaseType);
        }
    }
 
    //创建泛型结构
    public struct Point<T>
    { 
        //泛型状态数据
        private T xPos;
        private T yPos;
 
        //泛型构造函数
        public Point(T xVal,T yVal)
        {
            xPos = xVal;
            yPos = yVal;
        }
 
        //泛型属性
        public T X
        {
            get { return xPos; }
            set { xPos = value; }
        }
 
        public T Y
        {
            get { return yPos; }
            set { yPos = value; }
        }
 
        public override string ToString()
        {
            return string.Format("[{0},{1}]", xPos, yPos);
        }
 
        //重置字段为类型参数的默认值
        public void ResetPoint()
        {
            //default和泛型一起用时,它表示一个类型参数的默认值
            xPos = default(T);
            yPos = default(T);
        }
 
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            int a = 5;
            int b = 6;
 
            string str1 = "apple";
            string str2 = "orange";
 
            Console.WriteLine("Before swap:\n a={0} b={1}", a, b);
 
            //当泛型方法需要参数时,我们可以选择省略类型参数
            //MyHelperClass.Swap<int>(ref a, ref b);
            MyHelperClass.Swap(ref a, ref b);
            
            Console.WriteLine("After swap:\n a={0} b={1}", a, b);
            
            //如果方法不带任何参数,必须提供类型参数
            MyHelperClass.DisplayBaseClass<int>();
 
            Console.WriteLine();
 
            Console.WriteLine("Before swap:\n str1={0} str2={1}", str1, str2);
 
            //当泛型方法需要参数时,我们可以选择省略类型参数
            //MyHelperClass.Swap<string>(ref str1, ref str2);
            MyHelperClass.Swap(ref str1, ref str2);
            Console.WriteLine("After swap:\n str1={0} str2={1}", str1, str2);
 
            //如果方法不带任何参数,必须提供类型参数
            MyHelperClass.DisplayBaseClass<string>();
 
            Console.WriteLine();
 
            //使用int的point
            Point<int> p = new Point<int>(10, 10);
            Console.WriteLine("p.ToString()={0}",p.ToString());
            p.ResetPoint();
            Console.WriteLine("p.ToString()={0}", p.ToString());
 
            Console.WriteLine();
 
            //使用double的Point
            Point<double> p2 = new Point<double>(5.4, 3.3);
            Console.WriteLine("p.ToString()={0}", p2.ToString());
            p2.ResetPoint();
            Console.WriteLine("p.ToString()={0}", p2.ToString());
 
            Console.WriteLine();
 
            //交换两个Points
            Point<int> pointA = new Point<int>(20, 10);
            Point<int> pointB = new Point<int>(34, 1);
 
            Console.WriteLine("Before swap:\n {0} {1}", pointA, pointB);
            //当泛型方法需要参数时,我们可以选择省略类型参数
            //MyHelperClass.Swap<Point<int>>(ref pointA, ref pointB);
            MyHelperClass.Swap(ref pointA, ref pointB);
            Console.WriteLine("After swap:\n {0} {1}", pointA, pointB);
 
            Console.ReadLine();
        }
    }
}