C# 将对象强制转换为泛型类型的方法

C# 将对象强制转换为泛型类型的方法,c#,generics,casting,C#,Generics,Casting,关于 下面的例子 private static T deserialize<T>(string streng) where T : class { XmlSerializer ser = new XmlSerializer(typeof(T)); StringReader reader = new StringReader(streng); return ser.Deserialize(reader) as T; } 私有静态T反序列化(字符串强度),其中T

关于

下面的例子

private static T deserialize<T>(string streng) where T : class
{
    XmlSerializer ser = new XmlSerializer(typeof(T));
    StringReader reader = new StringReader(streng);
    return ser.Deserialize(reader) as T;
}
私有静态T反序列化(字符串强度),其中T:class
{
XmlSerializer ser=新的XmlSerializer(typeof(T));
StringReader=新StringReader(streng);
将序列反序列化(读取器)返回为T;
}

私有静态T反序列化(字符串强度)
{
XmlSerializer ser=新的XmlSerializer(typeof(T));
StringReader=新StringReader(streng);
返回(T)序列反序列化(读取器);
}
我习惯于将
对象作为类型
进行转换,所以当我发现我不能用
t
进行转换时,我有点困惑。然后,我发现了上面的问题,并在其中找到了
as T
编译器错误的解决方案

但是为什么在使用
对象作为T
时,T:class是必需的,而在使用
(T)对象时,T:class
不是必需的呢?
两种强制转换对象的方法之间的实际区别是什么?

因为
as
意味着强制转换可能失败并返回null。没有
:class
T
可以是
int
等-不能是
null
。使用(T)obj它只会在一阵火花中爆炸;无需处理
null

作为旁白(re
struct
),请注意,如果已知您正在强制转换为
可空的
,则可以使用
作为
——例如:

static T? Cast<T>(object obj) where T : struct
{
    return obj as T?;
}
静态T?强制转换(对象对象),其中T:struct
{
将obj返回为T?;
}
指定使用“as”进行强制转换,1)如果可以执行强制转换,2)如果不能执行,则返回
null
。对于无约束泛型参数(您的第二个示例),这是有问题的,因为T可能是一种值类型(如
int
),其变量不能包含
null


当泛型参数被约束为引用类型时(使用
约束),编译器可以对您的类型进行更多的推理,并了解
null
将始终是类型T的有效值。因此,“as”-样式转换可以安全使用。

只要运算符
返回
null
在失败的情况下,变量应该是类或可为null的结构:

同时,
cast
不需要这样的东西,您可以在struct上强制转换struct。

(T)obj
如果
obj
不能转换为
T
则抛出。如果您确定转换将起作用,则应使用
(T)obj

并使用
as
将测试替换为
is
,然后进行转换。当然,T需要是可空的(引用类型或
可空的
),因为
as
在失败时返回null。典型的模式是:

T x=y as T;
if(x!=null)
  DoSomething(x);

另一个区别是
as
仅适用于转换的子集。过载的强制转换等将被忽略。

哦,是的,谢谢abatishchev。没有名称空间更整洁:)这是非常有用的。我会接受你的回答,但系统告诉我等八分钟。MSDN文档可以在这里找到:(供进一步阅读)注意:由于
反序列化
返回
对象
,其他转换无论如何都不适用是的,在这种情况下,他无论如何都应该使用
(t)x
强制转换,因为他知道结果的类型是
T
T x=y as T;
if(x!=null)
  DoSomething(x);