(八)CSharp-泛型中的方法结构委托接口(2)

一、泛型方法

泛型方法可以在泛型和非泛型类以及结构和接口中声明。

(八)CSharp-泛型中的方法结构委托接口(2)_第1张图片

1、声明泛型方法

泛型方法具有类型参数列表和可选的约束。

  • 泛型方法有两个参数列表。

    • 封闭在圆括号内的方法参数列表。
    • 封闭在尖括号内的类型参数列表。
  • 要声明泛型方法,需要:

    • 在方法名称之后和方法参数列表之前放置类型参数列表;
    • 在方法参数列表后放置可选的约束子句。
public void PrintData(S,T)(S p,T t) where S: Person
{
...
}

//:类型参数列表
//(Sp,T t):方法参数列表
//where S: Person:约束子句

2、调用泛型方法

void DoStuff(T1 t1,T2 t2)
{
T1 someVar = t1;
T2 otherVar = t2;
}

DoStuff(sVal,iVal);
DoStuff(iVal,lVal);
//:类型实参

3、推断类型

编译可以从方法参数中推断类型参数,我们可以省略类型参数和调用中的尖括号。

DoStuff(sVal,iVal);

泛型方法的示例

//非泛型类
    class Simple
    {
        //泛型方法
        static public void ReverseAndPrint(T[] arr)
        {
            Array.Reverse(arr);

            //使用类型实参 T
            foreach (T item in arr)
                Console.Write($"{item.ToString() },");

            Console.WriteLine("");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //创建各种类型的数组
            var intArray = new int[] { 3, 5, 7, 9, 11 };
            var stringArray = new string[] { "first", "second", "third" };
            var doubleArray = new double[] { 3.567, 7.891, 2.345 };

            Simple.ReverseAndPrint(intArray);//调用方法
            Simple.ReverseAndPrint(intArray);//推断类型并调用

            Simple.ReverseAndPrint(stringArray);
            Simple.ReverseAndPrint(stringArray);

            Simple.ReverseAndPrint(doubleArray);
            Simple.ReverseAndPrint(doubleArray);
            Console.ReadKey();
        }
    }

二、扩展方法和泛型类

和非泛型类一样,泛型类的扩展方法:

  • 必须声明为 static;
  • 必须是静态类的成员;
  • 第一个参数类型中必须有关键字 this,后面是扩展的泛型类的名字。
   static class ExtendHolder
    {
        public static void Print(this Holder h)
        {
            T[] vals = h.GetValues();
            Console.WriteLine($"{ vals[0] },\t{ vals[1] },\t{ vals[2] }");
        }
    }

    class Holder
    {
        T[] Vals = new T[3];

        public Holder(T v0,T v1,T v2)
        {
            Vals[0] = v0;Vals[1] = v1;Vals[2] = v2;
        }

        public T[] GetValues() { return Vals; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var intHolder = new Holder(3, 5, 7);
            var stringHolder = new Holder("a1", "b2", "c3");
            intHolder.Print();
            stringHolder.Print();
            Console.ReadKey();
        }
    }

三、泛型结构

与泛型类相似,泛型结构可以有类型参数和约束。(规则和条件跟泛型类一样)

    //泛型结构
    struct PieceOfData
    {
        public PieceOfData(T value){ _data = value; }
        private T _data;
        public T Data
        {
            get { return _data; }
            set { _data = value; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
        //PieceOfData(10):构造类型
            var intData = new PieceOfData(10);
            var stringData = new PieceOfData("Hi there.");

            Console.WriteLine($"intData  =={ intData.Data }");
            Console.WriteLine($"stringData  =={ stringData.Data }");

            Console.ReadKey();
        }
    }

输出结果:

intData == 10
stringData == Hi there.

四、泛型委托

1、泛型委托

泛型委托和非泛型委托相似,不过类型参数决定了能接受什么样的方法。

delegate R MyDelegate(T value);
//R:返回类型
//:类型参数
//(T value):委托形参

有两个参数列表: 委托形参列表和类型参数列表。

类型参数的范围包括:

  • 返回类型;
  • 形参列表;
  • 约束子句。
 //泛型委托
    delegate void MyDelegate(T value);

    class Simple
    {
        //方法匹配委托
        static public void PrintString(string s)
        {
            Console.WriteLine(s);
        }

        static public void PrintUpperString(string s)
        {
            Console.WriteLine($"{s.ToUpper()}");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //创建委托的实例
            var mDel = new MyDelegate(Simple.PrintString);
            mDel += Simple.PrintUpperString;//添加方法

            mDel("Hi There.");//调用委托
            Console.ReadKey();
        }
    }

输出结果:

Hi There.
HI THERE.

2、另一个泛型委托示例

C# 的 LINQ 特性大量使用了泛型委托。

    //泛型委托
    public delegate TR Func(T1 P1, T2 P2);

    class Simple
    {
        //方法匹配委托
        static public string PrintString(int p1, int p2)
        {
            int total = p1 + p2;
            return total.ToString();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //创建委托实例
            var myDel = new Func(Simple.PrintString);
            Console.WriteLine($"Total:{ myDel(15,13) }");//调用委托
            Console.ReadKey();
        }
    }

输出结果:

Total:28

五、泛型接口

1、泛型接口

泛型接口的声明和非泛型接口的声明差不多,但是需要在接口名称之后的尖括号中放置类型参数。

泛型类型中实现泛型接口。

  //泛型接口
    interface IMyIfc
    {
        T ReturnIt(T inValue);
    }

    //实现泛型接口
    class Simple: IMyIfc
    {
        public S ReturnIt(S inValue)
        {
            return inValue;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var trivInt = new Simple();
            var trivString = new Simple();

            Console.WriteLine($"{ trivInt.ReturnIt(5) }");
            Console.WriteLine($"{ trivString.ReturnIt("Hi there.") }");

            Console.ReadKey();
        }
    }

输出结果:

5
Hi there.

2、使用泛型接口的示例

非泛型类型中实现泛型接口。

    //泛型接口
    interface IMyIfc
    {
        T ReturnIt(T inValue);
    }

    //非泛型类
    //
    class Simple: IMyIfc, IMyIfc
    {
        //实现 int 类型接口
        public int ReturnIt(int inValue)
        {
            return inValue;
        }

        //实现 string 类型接口
        public string ReturnIt(string inValue)
        {
            return inValue;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Simple trivial = new Simple();
            Console.WriteLine($"{ trivial.ReturnIt(5) }");
            Console.WriteLine($"{ trivial.ReturnIt("Hi there.") }");

            Console.ReadKey();
        }
    }

输出结果:

5
Hi there.

3、泛型接口的实现必须唯一

实现泛型类型接口时,必须保证类型实参的组合不会在类型中产生两个重复的接口。

    //泛型接口
    interface IMyIfc
    {
        T ReturnIt(T inValue);
    }
    
//错误:IMyIfc, IMyIfc,
//如果 S 为 int 类型就跟第一个接口重复了
    class Simple: IMyIfc, IMyIfc
    {
        //实现 int 类型接口
        public int ReturnIt(int inValue)
        {
            return inValue;
        }

        //实现 string 类型接口
        public S ReturnIt(S inValue)
        {
            return inValue;
        }
    }

你可能感兴趣的:(CSharp,c#)