C# 用于铸造泛型的规避型系统

C# 用于铸造泛型的规避型系统,c#,generics,casting,C#,Generics,Casting,C#不会让我把一个类型的t转换成一个我可以证明的t类型。如何将T转换为该类型 public static T _cast<T> (object o) { if (typeof(T) == typeof(string)) { return (T) o.ToString(); // Compiler YELLS! } throw new InvalidCastException("missing compiler generated case");

C#不会让我把一个类型的
t
转换成一个我可以证明的
t
类型。如何将
T
转换为该类型

public static T _cast<T> (object o) {
    if (typeof(T) == typeof(string)) {
        return (T) o.ToString(); // Compiler YELLS!
    }
    throw new InvalidCastException("missing compiler generated case");
}
publicstatict\u-cast(对象o){
if(typeof(T)=typeof(string)){
return(T)o.ToString();//编译器大叫!
}
抛出新的InvalidCastException(“缺少编译器生成的案例”);
}

我正在编写一个程序,它从C++到C语言生成代码。这个
\u cast
操作我想用来代替C++的
操作符T()

没有从字符串到其他类型的转换。编译器告诉您,它不知道如何执行您要求的操作。如果你提供更多关于你要做什么的细节,也许有人可以提供一些建议。

没有从字符串到其他类型的转换。编译器告诉您,它不知道如何执行您要求的操作。如果你提供更多关于你想做什么的细节,也许有人可以提供一些建议。

通常我不会回答我自己的问题,但我只是想出了解决办法:在转换到
t
之前,向下转换到
object

public static T _cast<T> (object o) {
    if (typeof(T) == typeof(string)) {
        return (T)(object) o.ToString();
    }
    throw new InvalidCastException("missing compiler generated case");

}
publicstatict\u-cast(对象o){
if(typeof(T)=typeof(string)){
返回(T)(对象)o.ToString();
}
抛出新的InvalidCastException(“缺少编译器生成的案例”);
}

通常我不会回答自己的问题,但我只是想出了一个解决方案:向下转换到
对象,然后再转换到
t

public static T _cast<T> (object o) {
    if (typeof(T) == typeof(string)) {
        return (T)(object) o.ToString();
    }
    throw new InvalidCastException("missing compiler generated case");

}
publicstatict\u-cast(对象o){
if(typeof(T)=typeof(string)){
返回(T)(对象)o.ToString();
}
抛出新的InvalidCastException(“缺少编译器生成的案例”);
}

强制转换和解析之间有区别。我认为您想要的是尝试解析字符串

int stringToNum = (int)"123";  //will not compile

int stringToNum2 = int.Parse("123");

强制转换和解析之间有区别。我认为您想要的是尝试解析字符串

int stringToNum = (int)"123";  //will not compile

int stringToNum2 = int.Parse("123");

我认为比你的双重角色更优雅的解决方案是使用
as
关键字。像这样:

return o.ToString() as T;

我没有尝试过,但编译器不应该有问题,因为当它不能将字符串转换为t时,它将返回null,这在您的条件中当然不会。我认为比您的双重转换更优雅的解决方案是使用
作为
关键字。像这样:

return o.ToString() as T;


我没有尝试过,但编译器不应该有问题,因为当它不能将字符串转换为t时,它将返回null,这在您的条件中当然不会执行。

这不是我所说的“转换”。该方法仅在T为字符串时才执行有用的操作;否则只返回null或零。e、 g._铸造(10)返回0。这对于任何使用它的人来说都是非常不清楚和令人惊讶的。我重复一遍:这是计算机生成的代码!谁在乎它是否可读?但是将
默认值(T)
更改为抛出会更好。。。所以我会这么做。为什么这个问题被否决了?这不是我所说的“演员阵容”。该方法仅在T为字符串时才执行有用的操作;否则只返回null或零。e、 g._铸造(10)返回0。这对于任何使用它的人来说都是非常不清楚和令人惊讶的。我重复一遍:这是计算机生成的代码!谁在乎它是否可读?但是将
默认值(T)
更改为抛出会更好。。。我会的。为什么这个问题被否决了?是的,这是正确的答案。它通常被称为“双重演员”。我(很少)也需要这样做。是的,这是正确的答案。它通常被称为“双重演员”。我(很少)也需要这样做。不,OP尝试将已经是字符串的对象强制转换为字符串(type
T
)。不,OP尝试将已经是字符串的对象强制转换为字符串(type
T
).+1当可以为模板添加
class
限制时,有用的方法,如
class MyTest,其中T:class
。否则会出现编译错误,因为
as
对值类型无效。@AlexeiLevenkov真可惜。我没有考虑这一点。非常感谢您指出这一点!让我回击你!:)@阿列克谢列文科夫,你确定吗?我刚刚试过,它编译得很好:
void M(T T){var s=T as string;}
@KirkWoll您对T的约束是什么?也就是说,在您的类声明中,您是否有任何``where T:`子句?@Mithon,我给出的示例实际上是完整的——它是一个声明名为
T
的类型参数的方法,没有任何约束。+1当您可以为模板添加
class
约束时,这是一种有用的方法,例如
class MyTest where T:class
。否则会出现编译错误,因为
as
对值类型无效。@AlexeiLevenkov真可惜。我没有考虑这一点。非常感谢您指出这一点!让我回击你!:)@阿列克谢列文科夫,你确定吗?我刚刚试过,它编译得很好:
void M(T T){var s=T as string;}
@KirkWoll您对T的约束是什么?也就是说,在您的类声明中,是否有任何``where T:`子句?@Mithon,我给出的示例实际上是完整的——它是一个声明名为
T
的类型参数的方法,没有任何约束。