C# · 12月 24, 2021

c# – 通用方法无法调用正确的重载

注意:我正在使用Mono环境,如果这有所不同.

我正在写一些测试,为了帮助我,我有以下通用方法:

static MemoryStream writeValue<T>(T inVal){ MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); encode_any(bw,inVal); return ms;}

我的想法是,这会调用我的一个encode_any重载,它会委托给特定于类型的方法:

public static void encode_any(BinaryWriter writer,Int32 val) { encode_int32(writer,val); }public static void encode_any(BinaryWriter writer,Int64 val) { encode_int64(writer,Float val) { encode_float(writer,val); }…etc…public static void encode_any(BinaryWriter writer,bool val) { encode_bool(writer,val); }

我想这样做的原因是我可以在每种情况下调用正确的实现,而不需要几个版本的’writeValue’,并且在选择要调用的encode_函数之前不检查每个项的运行时类型.

然而,似乎编译器试图解决writeValue的重载而不知道T将是什么类型,所以我得到这个错误:

错误CS1502:’BinarySerialiser.encode_any(System.IO.BinaryWriter,bool)’的最佳重载方法匹配有一些无效的参数
错误CS1503:参数’#2’无法将’T’表达式转换为’bool’类型

我注意到这不是特别关于bool – 如果我重新排列我的encode_any函数的顺序,它总是尝试使用最后一个.也许它只是尝试每一个,然后只有当它用完替代品时才会发出错误.

这种代码在C下可以正常工作,其中writeValue仅在T已知时编译,但这似乎不是这种情况,我怀疑这是因为C#在运行时处理泛型类型.

我可以改变我的方法来完成这项工作,如果是这样的话?

解决方法 这不是C而是C#.这意味着,您拥有的代码不起作用,因为在C#中的泛型类中,您可以访问泛型类型参数的所有已知成员.知道哪些成员完全取决于您对泛型类型参数的约束. IIRC,在C中它有点不同.
无论如何,在你的情况下,T没有约束,因此编译器对该泛型参数一无所知.但是,没有任何约束可以让你做,你想做什么.
如果您使用的是.NET 4.0,则可以使用新的dynamic关键字: static MemoryStream writeValue<T>(T inVal){ MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); dynamic dynamicValue = inVal; encode_any(bw,dynamicValue); return ms;}

因为您使用的是Mono,我认为您不能使用它,因为Mono尚未实现此关键字.看起来Mono已经实现了DLR,请参阅下面的paolo链接.