对泛型类型的参数限制 泛型怎么传string参数
各位老铁们,大家好,今天由我来为大家分享对泛型类型的参数限制,以及泛型怎么传string参数的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!
请教一个unity有关于泛型参数的问题
在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制。如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where上下文关键字指定的。下表列出了六种类型的约束:
约束
说明
T:结构
类型参数必须是值类型。可以指定除 Nullable以外的任何值类型。有关更多信息,请参见使用可空类型(C#编程指南)。
T:类
类型参数必须是引用类型,包括任何类、接口、委托或数组类型。
T:new()
类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new()约束必须最后指定。
T:<基类名>
类型参数必须是指定的基类或派生自指定的基类。
T:<接口名称>
类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
T:U
为 T提供的类型参数必须是为 U提供的参数或派生自为 U提供的参数。这称为裸类型约束。
使用约束的原因
如果要检查泛型列表中的某个项以确定它是否有效,或者将它与其他某个项进行比较,则编译器必须在一定程度上保证它需要调用的运算符或方法将受到客户端代码可能指定的任何类型参数的支持。这种保证是通过对泛型类定义应用一个或多个约束获得的。例如,基类约束告诉编译器:仅此类型的对象或从此类型派生的对象才可用作类型参数。一旦编译器有了这个保证,它就能够允许在泛型类中调用该类型的方法。约束是使用上下文关键字 where应用的。
[转]
泛型约束基本上有五种:
值类型约束:要求泛型参数必须是值类型,例如int,short以及自定义的stuct等
public class MyClass2<T>
where T: struct//这个泛型类只接受值类型的泛型参数
{
}
引用类型约束:要求泛型参数必须是引用类型,例如string,object,以及自定义的class
public class MyClass<T>
where T:class//这个泛型类只接受引用类型的泛型参数
{
}
构造函数约束:要求泛型参数必须有构造函数
public class MyClass3<T>
where T: new()
{
}
接口约束:要求泛型参数必须实现某个接口
public class MyClass4<T>
where T: System.IComparable
{
}
基类约束:要求泛型参数必须继承某个基类
public class MyClass5<T>
where T: Customer
{
}
java学习,泛型方法的泛型参数的判断问题。谢谢~
这个问题,表示楼主蛮有专研精神的
编译器判断范型方法的实际类型参数的过程称为类型推断。
我们从eclipse里面可以看到,显示此时的实际调用代码是
fromArrayToCollection(Number[]a,Collection<Number>c)
泛型类型推断有个重要的规则:
当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型
这种泛型,我建议使用限定通配符显式的标识关系<T extends Number>
//声明一个泛型方法,该泛型方法中带一个T类型形参,
static<TextendsNumber>voidfromArrayToCollection(T[]a,Collection<T>c){
for(To:a){
c.add(o);
}
}
C#如何将类型Type作为泛型T的参数T传递
简单的例子:
bool Method<T>(bool parameter) where T:class
{return parameter;}
这是一个完整的泛型方法,限制符T:class表示了泛型T的类型限制,请在MSDN查找“泛型类型约束”词条
使用泛型方法一般用于涉及泛型(T)的方法:
泛型参数里有至少一个类型,如Method<T1,T2>() where...
返回值里涉及泛型,如 List<T> Method<T>() where...
方法内部需要以参数泛型类型为据做运算,如方法内容是 return T is IComparable;
参数中涉及不确定的类型,如Method<T>(List<T> 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<TElement> ElementsMax<TParam1, TParam2, TElement>(TParam1 p1, TParam2 p2)
where TParam1: IEnumerable<TElement>
where TParam2: IEnumerable<TElement>
where TElement: IComparable<TElement>
方法内容我这里直接写上了,不用细看,基本思路就是逐一取出两个参数序列的元素进行比较填入新序列。唯一需要注意的是两个参数序列的长度未必相等。
完整的方法,已测:
List<TElement> ElementsMax<TParam1, TParam2, TElement>(TParam1 p1, TParam2 p2)
where TParam1: IEnumerable<TElement>
where TParam2: IEnumerable<TElement>
where TElement: IComparable<TElement>
{
List<TElement> rtn= new List<TElement>();
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<int> lst= new List<int>{ 3, 1, 5, 5, 9};
List<int> result= ElementsMax<int[], List<int>, int>(array, lst);
outputStr="";
for(int index= 0; index< result.Count(); outputStr+= result[index++].ToString()+",");
MessageBox.Show(outputStr);
//char测试
string s1="Hello world";
Queue<char> s2= new Queue<char>("Happy new year");
List<char> result2= ElementsMax<string, Queue<char>,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<int> result3= ElementsMax<List<int>, int[], int>(ElementsMax<int[], int[], int>(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我。
文章到此结束,如果本次分享的对泛型类型的参数限制和泛型怎么传string参数的问题解决了您的问题,那么我们由衷的感到高兴!