class Mock
{
public static explicit operator String(Mock s)
{
return "ok";
}
}
static T GetValue<T>(object o)
{
return (T)o;
}
Mock m = new Mock();
var v1 = (string) m;
var v2 = GetValue<string>(m); // InvalidCastException is thrown.
// How to modify GetValue method
// internally, without changing its
// signature, for this casting to work ?
此致
答案 0 :(得分:2)
两个选项:
使用反射可能会很痛苦。如果你可以逃脱它,那么动态方法就更简单了:
public static T GetValue<T>(dynamic d)
{
return (T) d;
}
这不是对签名的特别重大改变,但如果你想保持完全相同,你可以使用:
public static T GetValue<T>(object o)
{
dynamic d = o;
return (T) d;
}
答案 1 :(得分:1)
直接强制转换成功且GetValue
方法失败的原因是因为直接强制转换方法在Mock<T>
类型上使用explicitcast运算符。此显式转换运算符在通用版本中不可用,因为C#编译器只看到T
,因此不绑定到隐式转换运算符,而是选择执行CLR转换。
最简单的方法是添加一个接口来表示此转换,然后约束T
来实现接口
interface IConvertToString {
string Convert();
}
public class Mock : IConvertToString {
public string Convert() {
return "ok";
}
}
public static T GetValue<T>(T o) where T : IConvertToString {
return o.ConvertToString();
}
答案 2 :(得分:0)
这个怎么样:var v2 = GetValue<string>((string)m);
?
这不会修改GetValue方法,而是强制转换发送到其中的参数。你保留了你的签名。演员看起来有点多余,但你必须指定GetValue的类型......