Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从对象引用执行转换 类模拟 { 公共静态显式运算符字符串(模拟s) { 返回“ok”; } } 静态T GetValue(对象o) { 返回(T)o; } Mock m=新Mock(); var v1=(字符串)m; var v2=GetValue(m);//引发InvalidCastException。 //如何修改GetValue方法 //在内部,不改变其 //签名,让这个角色发挥作用?_C# - Fatal编程技术网

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();
}