C# 如何从对象引用执行转换 类模拟 { 公共静态显式运算符字符串(模拟s) { 返回“ok”; } } 静态T GetValue(对象o) { 返回(T)o; } Mock m=新Mock(); var v1=(字符串)m; var v2=GetValue(m);//引发InvalidCastException。 //如何修改GetValue方法 //在内部,不改变其 //签名,让这个角色发挥作用?
关于两个选项:C# 如何从对象引用执行转换 类模拟 { 公共静态显式运算符字符串(模拟s) { 返回“ok”; } } 静态T GetValue(对象o) { 返回(T)o; } Mock m=新Mock(); var v1=(字符串)m; var v2=GetValue(m);//引发InvalidCastException。 //如何修改GetValue方法 //在内部,不改变其 //签名,让这个角色发挥作用?,c#,C#,关于两个选项: 使用反射查找转换并调用它 如果您使用的是C#4,请使用动态键入 使用反射可能是痛苦的。如果您能够侥幸逃脱,动态方法会更简单: class Mock { public static explicit operator String(Mock s) { return "ok"; } } static T GetValue<T>(object o) { return (T)o; } Mock m = new Mock(
- 使用反射查找转换并调用它
- 如果您使用的是C#4,请使用动态键入
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 ?
公共静态T GetValue(动态d)
{
返回(T)d;
}
这并不是对签名的一个特别剧烈的更改,但如果您想保持完全相同,可以使用:
public static T GetValue<T>(dynamic d)
{
return (T) d;
}
publicstatict GetValue(对象o)
{
动态d=o;
返回(T)d;
}
直接强制转换成功而GetValue
方法失败的原因是,直接强制转换方法在Mock
类型上使用了explicitcast运算符。此显式强制转换运算符在泛型版本中不可用,因为C#编译器只看到T
,因此不绑定到隐式转换运算符,而是选择执行CLR转换
最简单的方法是添加一个接口来表示此转换,然后约束T
来实现该接口
public static T GetValue<T>(object o)
{
dynamic d = o;
return (T) d;
}
接口IConvertToString{
字符串转换();
}
公共类模拟:IConvertToString{
公共字符串转换(){
返回“ok”;
}
}
公共静态T GetValue(TO),其中T:IConvertToString{
返回o.ConvertToString();
}
这个怎么样:var v2=GetValue((string)m)代码>
这不会修改GetValue方法,而是强制转换发送到其中的参数。你保留你的签名。强制转换看起来有点多余,但无论如何都必须指定GetValue的类型
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();
}