LINQ .Cast()扩展方法失败但(类型)对象有效
要在一些LINQ to SQL对象和DTO之间进行转换,我们在DTO上创建了显式的转换运算符。 这样我们就可以做到以下几点:
DTOType MyDTO = (LinqToSQLType)MyLinq2SQLObj;
这很好用。
但是,当您尝试使用LINQ .Cast()扩展方法进行强制转换时,它会抛出一个无效的强制转换exception,表示无法将类型Linq2SQLType转换为类型为DTOType。 即以下不起作用
List Names = dbContact.tNames.Cast() .ToList();
但以下工作正常:
DAL.tName MyDalName = new DAL.tName(); DTO.Name MyDTOName = (DTO.Name)MyDalName;
以下也行得正常
List Names = dbContact.tNames.Select(name => (DTO.Name)name) .ToList();
为什么.Cast()扩展方法会抛出无效的强制转换exception? 我过去曾多次使用.Cast()扩展方法,当你将类似基类型的类型转换为派生类型时,它可以正常工作,但是当对象有一个显式的强制转换操作符时,它就会失败。
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有一篇关于C#中演员操作符行为的精彩文章 – 总是值得一读。
如果您对Linq程序集进行反编译,则会得到类似以下内容的代码。 之前的答案是正确的,最终演员阵容从“对象”到目标类型,对于自定义类型总是会失败。
private static IEnumerable CastIterator ( IEnumerable source ) { foreach(object current in source) { yield return (TResult)( (object)current ); } yield break; } public static IEnumerable DCast ( this IEnumerable source ) { IEnumerable enumerable = source as IEnumerable ; if(enumerable != null) { return enumerable; } if(source == null) { throw new ArgumentNullException( "source" ); } return CastIterator ( source ); }
TFish
对于那些遇到这个问题寻找解决方法的人……
Dim res = arrayOfStrings.Select(Function(__) CType( __, YourType ))
不确定C#的确切语义,但我确信这很容易。
上述就是C#学习教程:LINQ .Cast()扩展方法失败但(类型)对象有效分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1013322.html