注意:我正在使用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, val); }
public static void encode_any(BinaryWriter 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#在运行时处理泛型类型
我可以改变我的方法来完成这项工作,如果是这样的话?
答案 0 :(得分:8)
这不是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链接。
答案 1 :(得分:1)
您的问题是重载解析是在编译时完成的,而不是运行时 - 在本例中是在以下行:
encode_any(bw, inVal);
inVal
除了inVal
之外没有类型约束(或者可以装箱)对象,因此只有接受对象的重载被认为是重载解析。
我的方法可能是创建一个encode_any
重载,它接受一个对象并确定在运行时调用哪个方法。