如何使用泛型给非泛型方法传递参数?为什么下面的代码不能编译?如果通用类型是“int”、“bool”、“char”等,我如何创建调用适当“BitConverter.GetBytes”重载的通用方法?更一般地说,你如何创建一个泛型方法,它根据泛型参数的类型调用一个非泛型方法?使用系统;公共类测试{publicstaticvoidMain(){varf=newFoo();f.GetBytes(10);//应该调用BitConverter.GetBytes(int);f.GetBytes(真);//应该调用BitConverter.GetBytes(bool);f.GetBytes('A');//应该调用BitConverter.GetBytes(char);}}publicclassFoo{publicbyte[]GetBytes(TSourceinput){BitConverter.GetBytes(input);更一般地说,你如何创建一个泛型方法,它根据泛型参数的类型调用一个非泛型方法?一般来说,你不能,除非有问题的方法将System.Object作为参数。问题是泛型不限于方法调用参数允许的类型。最接近的是使用运行时绑定:publicbyte[]GetBytes(TSourceinput){dynamicobj=input;BitConverter.GetBytes(obj);}这会将方法绑定逻辑推送到运行时,如果没有合适的方法可以调用,它就会抛出。这不起作用的原因是泛型方法仍然静态地解析对其中方法的调用。由于TSource可以是任何类型,它只能调用带有对象参数的BitConverter上的方法。编译失败,因为它不存在。获得所需行为的唯一方法是使用动态:publicbyte[]GetBytes(TSourceinput){BitConverter.GetBytes((dynamic)input);}虽然泛型参数现在是多余的,但您没有类型安全。在这种情况下,您可以创建许多匹配的重载,例如publicbyte[]GetBytes(boolb){...}publicbyte[]GetBytes(inti){...}或采用Func参数并包装您需要的每个BitConverter方法,例如publicvoidDoSomething(Tinput,Funcf){byte[]bytes=f(input);//处理字节}DoSomething(true,BitConverter.GetBytes);这可能会给你更多的灵活性。在调用BitConverter.GetBytes的代码中,type是TSource,所以不能静态绑定调用。您可以通过使用动态调用来解决这个问题,这意味着它编译得很好,然后在运行时得到解析:...publicbyte[]GetBytes(dynamicinput){returnBitConverter.GetBytes(input);您将使用动态调用支付性能损失,如果没有合适的调用方法可用,您将获得运行时异常。鉴于BitConverter.GetBytes只有“10”重载,因此不能像这样显式反映它们:}publicbyte[]GetBytes(charinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(doubleinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(floatinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(intinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(shortinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(longinput){return}publicbyte[]GetBytes(uintinput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(ulonginput){returnBitConverter.GetBytes(input);}publicbyte[]GetBytes(ushortinput){returnBitConverter.GetBytes(input);它不是一般的(你要求它)并且不能扩展到更复杂的例子,但如果数字很小那么它是一种考虑的方法。如果您愿意提高性能,可以使用反射和对象GetBytes的扩展。示例....publicstaticclassExtensions{#regionFieldspublicstaticTypebcType;#endregion#region构造函数静态扩展(){bcType=typeof(BitConverter);}#endregionpublicstaticbyte[]GetBytes(这个对象值){TypetypeObj=value.GetType();MethodInfomiGetBytes=bcType.GetMethod("GetBytes",newType[]{typeObj});if(miGetBytes==null)thrownewInvalidOperationException("方法:BitConverter上的GetBytes没有接受一个类型参数的重载:"+typeObj.FullName);byte[]bytesRet=(byte[])miGetBytes.Invoke(null,newobject[]{obj});返回bytesRet;}}所以GetBytes接受一个对象。然后它获取其类型并尝试根据传入的对象类型从BitConverter获取MethodInfo。如果它找不到接受该类型作为参数的重载,则会抛出InvalidOperationexception。如果是,则调用将obj实例作为值传递并返回字节数组。使用代码,//确保在运行此代码的位置定义了扩展命名空间。Console.WriteLine(((ushort)255).GetBytes().ToBase64());Console.WriteLine(10.0.GetBytes().ToBase64());Console.WriteLine(((int)2000000000).GetBytes().ToBase64());Console.WriteLine(((short)128).GetBytes().ToBase64());//下面导致错误Console.WriteLine("cool".GetBytes().ToBase64());//因为BitConvert.GetBytes没有接受字符串类型参数的重载。您需要使用反射来执行此操作。从BitConverter静态类型中获取GetBytes方法组。提取第一个参数为TSource类型的重载。该特定方法是通过Invoke方法调用的。如果您不熟悉其中的一些内容,我可以使用这些步骤的代码来扩展答案。编辑:或者按照其他人的建议使用dynamic并为自己节省一些工作。您的代码无法编译,因为编译器无法验证BitConverter.GetBytes()是否接受任何TSource类型。您可以单独检查每个类型并强制转换:以上是C#学习教程:如何使用泛型将参数传递给非泛型方法?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——publicbyte[]GetBytes(TSourceinput){vart=typeof(TSource);返回(t==typeof(int))?BitConverter.GetBytes((int)(对象)输入):(t==typeof(bool))?BitConverter.GetBytes((布尔)(对象)输入):(t==typeof(char))?BitConverter.GetBytes((字符)(对象)输入):空;}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
