C#如何将类型Type作为泛型T的参数T传递

2024-12-31 12:54:45
推荐回答(4个)
回答1:

简单的例子:

bool Method(bool parameter) where T:class

{return parameter;}


这是一个完整的泛型方法,限制符T:class表示了泛型T的类型限制,请在MSDN查找“泛型类型约束”词条http://msdn.microsoft.com/zh-cn/library/bb384067.aspx


使用泛型方法一般用于涉及泛型(T)的方法:

  1. 泛型参数里有至少一个类型,如Method() where...

  2. 返回值里涉及泛型,如 List Method() where...

  3. 方法内部需要以参数泛型类型为据做运算,如方法内容是 return T is IComparable;

  4. 参数中涉及不确定的类型,如Method(List param) where...


如果仅需要传入类型T而不需要返回涉及T的值,完全可以使用 Method(Type t)来替代。

应该注意的一点是,泛型方法存在的意义在于减少了非常多的冗余代码,它并不能消除或者自动处理如1楼中楼主所说的if/else逻辑(但是可以让你只写一次if/else而非几十上百次)。


我不太确定你到底想问什么,如果只是要单纯的用法,下面给你一个我现写的例子,该例子涉及上述4个使用场景。虽然看起来有点复杂,但是完全理解后熟练应用泛型方法不成问题。


我们的目标是:写一个方法,接收两个类型不定但继承自IEnumerable(可枚举接口)的参数,输出一个列表,其内是两个参数的每个元素比较大小后较大的元素的集合。例如,输入{1,3,4,5}和{2,2},应该输出{2,3,4,5}。


现在我们分析一下,首先这个方法需要指出两个参数的类型,这里定为泛型类型T1和T2,这里的限定是IEnumerable,这样我们才可随意枚举这两个参数的元素。


由于要比较元素大小而元素的类型不确定,所以还需要一个泛型类型指定两个参数中元素的类型,这里用泛型类型TElement。因为需要比较大小,这里加上限定IComparable,以防调用者送进来根本不能进行Compare的元素类型。


加上我们期待的输出,方法的签名就是:

 List ElementsMax(TParam1 p1, TParam2 p2)

            where TParam1 : IEnumerable

            where TParam2 : IEnumerable

            where TElement : IComparable

方法内容我这里直接写上了,不用细看,基本思路就是逐一取出两个参数序列的元素进行比较填入新序列。唯一需要注意的是两个参数序列的长度未必相等。


完整的方法,已测:


List ElementsMax(TParam1 p1, TParam2 p2)

            where TParam1 : IEnumerable

            where TParam2 : IEnumerable

            where TElement : IComparable

        {

            List rtn = new List();

            int p1Length = p1.Count();

            int p2Length=p2.Count();

            for (int index = 0; index < Math.Max(p1.Count(), p2.Count()); index++)

            {

                //如果此p1和p2在index位置都有元素则比大小

                //如果一方序列已空则判定未空的序列在index位置的元素为大

                TElement compRslt = default(TElement);

                if (index < p1Length && index < p2Length)

                    compRslt = p1.ElementAt(index).CompareTo(p2.ElementAt(index)) >= 0 ? p1.ElementAt(index) : p2.ElementAt(index);

                else if (index < p1Length && index >= p2Length)

                    compRslt = p1.ElementAt(index);

                else if (index >= p1Length && index < p2Length)

                    compRslt = p2.ElementAt(index);

                //如果compRslt的值不是我们一开始构造的默认值,说明比较有结果,存储

                if (compRslt.CompareTo(default(TElement))!=0)

                    rtn.Add(compRslt);

            }

            //btw,ICollection在Linq下有Zip方法可以条件式合并两个序列。

            return rtn;

        }


然后我们试试调用,可以直观的看到使用泛型方法的好处。

            string outputStr;

            //int测试

            int[] array = new int[] { 2, 1, 1, 6 };

            List lst = new List { 3, 1, 5, 5, 9 };

            List result= ElementsMax, int>(array, lst);

            outputStr = "";

            for (int index = 0; index < result.Count(); outputStr += result[index++].ToString() + ",") ;

            MessageBox.Show(outputStr);

            //char测试

            string s1 = "Hello world";

            Queue s2 = new Queue("Happy new year");

            List result2 = ElementsMax,char>(s1, s2);

            outputStr = "";

            for (int index = 0; index < result2.Count(); outputStr += result2[index++].ToString()+",") ;

            MessageBox.Show(outputStr);

            //还可以迭代使用

            int[] a1 = new int[] { 1, 3, 5, 7, 9 };

            int[] a2 = new int[] { 2, 4, 6, 8 };

            int[] a3=new int[]{8,8,8,8,8};

            List result3 = ElementsMax, int[], int>(ElementsMax(a1, a2), a3);

            outputStr = "";

            for (int index = 0; index < result3.Count(); outputStr += result3[index++].ToString() + ",") ;

            MessageBox.Show(outputStr);


实际的三组输出是:

3,1,5,6,9,

H,e,p,p,y, ,w,o,w,l,y,e,a,r,

8,8,8,8,9,

符合我们的预期。


就说到这里,有什么问题可以PM我。

回答2:

C# 的泛型都是以类或方法后加尖括号来传:fun()

回答3:

按你的字面的意思我可以理解为:
switch(Systen,Type)
case 1:
Method<1>();
breake;
default:
break;

这样能理解么?

回答4:

推迟处理,