要在一些LINQ to SQL对象和DTO之间进行转换,我们在DTO上创建了显式的转换运算符。这样我们就可以做到以下几点:
DTOType MyDTO = (LinqToSQLType)MyLinq2SQLObj;
这很有效。
但是当你尝试使用LINQ .Cast()扩展方法进行强制转换时,它会抛出一个无效的强制转换异常,说不能将类型Linq2SQLType转换为类型为DTOType。即以下不起作用
List<DTO.Name> Names = dbContact.tNames.Cast<DTO.Name>()
.ToList();
但下面的工作正常:
DAL.tName MyDalName = new DAL.tName();
DTO.Name MyDTOName = (DTO.Name)MyDalName;
以下也可以正常使用
List<DTO.Name> Names = dbContact.tNames.Select(name => (DTO.Name)name)
.ToList();
为什么.Cast()扩展方法会抛出无效的强制转换异常?我过去曾经多次使用.Cast()扩展方法,当你将类似基类型的类型转换为派生类型时,它可以正常工作,但是当对象有一个显式的强制转换操作符时,它就会失效。
答案 0 :(得分:24)
Cast<>
扩展方法不应用用户定义的转换。它只能转换为接口或所提供类型的类层次。
用户定义的转换在编译时根据表达式中涉及的静态类型进行标识。它们不能用作运行时转换,因此以下内容是非法的:
public class SomeType
{
public static implicit operator OtherType(SomeType s)
{
return new OtherType();
}
}
public class OtherType { }
object x = new SomeType();
OtherType y = (OtherType)x; // will fail at runtime
UDC是否存在从SomeType
到OtherType
并不重要 - 它不能通过object
类型的引用应用。试图运行上面的代码会在运行时失败,报告如下:
System.InvalidCastException:
Unable to cast object of type 'SomeType' to type 'OtherType'
Cast<>()
只能执行保留转化的表示...这就是您无法使用它来应用用户定义的转化的原因。
Eric Lippert撰写了一篇关于behavior of the cast operator in C#的精彩文章 - 总是值得一读。
答案 1 :(得分:2)
如果您对Linq程序集进行反编译,则会得到类似以下内容的代码。之前的答案是正确的,最终演员阵容从“对象”到目标类型,对于自定义类型总是失败。
private static IEnumerable<TResult> CastIterator<TResult>( IEnumerable source )
{
foreach(object current in source)
{
yield return (TResult)( (object)current );
}
yield break;
}
public static IEnumerable<TResult> DCast<TResult>( this IEnumerable source )
{
IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
if(enumerable != null)
{
return enumerable;
}
if(source == null)
{
throw new ArgumentNullException( "source" );
}
return CastIterator<TResult>( source );
}
TFish
答案 2 :(得分:0)
对于那些遇到这个问题寻找解决方法的人......
<?php
foreach ($anna_array as $x => $x_value) {
$speler1_prestaties = "<span class=\"white bold\">".str_pad($count1++, 2, "0", STR_PAD_LEFT)."</span> ".$x.":
<span class=\"orange\">".$x_value." "(".$points .")></span><br />";
echo $player1_info;
?>
不确定C#的确切语义,但我确定它非常简单。