C# 扩展方法失败,但(type)对象正常工作
为了在一些LINQ到SQL对象和DTO之间转换,我们在DTO上创建了显式强制转换操作符。这样我们可以做到以下几点:C# 扩展方法失败,但(type)对象正常工作,c#,linq,casting,extension-methods,C#,Linq,Casting,Extension Methods,为了在一些LINQ到SQL对象和DTO之间转换,我们在DTO上创建了显式强制转换操作符。这样我们可以做到以下几点: DTOType MyDTO = (LinqToSQLType)MyLinq2SQLObj; 这很有效 但是,当您尝试使用LINQ.cast扩展方法强制转换时,它会抛出一个无效的强制转换异常,表示无法将类型Linq2SQLType强制转换为类型DTOType。i、 e.以下选项不起作用 List<DTO.Name> Names = dbContact.tNames.Ca
DTOType MyDTO = (LinqToSQLType)MyLinq2SQLObj;
这很有效
但是,当您尝试使用LINQ.cast扩展方法强制转换时,它会抛出一个无效的强制转换异常,表示无法将类型Linq2SQLType强制转换为类型DTOType。i、 e.以下选项不起作用
List<DTO.Name> Names = dbContact.tNames.Cast<DTO.Name>()
.ToList();
下面的方法也很好用
List<DTO.Name> Names = dbContact.tNames.Select(name => (DTO.Name)name)
.ToList();
为什么.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是否从某个类型存在到另一个类型并不重要——它不能通过object类型的引用应用。尝试运行上述代码将在运行时失败,报告如下:
System.InvalidCastException:
Unable to cast object of type 'SomeType' to type 'OtherType'
强制转换只能执行保留表示的转换。。。这就是为什么不能使用它来应用用户定义的转换
Eric Lippert有一篇关于Linq程序集的伟大文章,这篇文章总是值得一读。如果您对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对于那些遇到此问题并正在寻找解决方法的人
Dim res = arrayOfStrings.Select(Function(__) CType( __, YourType ))
不确定C的确切语义,但我相信这很容易。我的问题是,我已经观察到了您通过经验描述的行为,我想问的是,为什么它不适用于用户定义的转换。与显式cast操作符不起作用的有什么不同之处,它是如何进行转换的?Ben:在你写评论时,我正在详细阐述我的答案:让我知道这是否为cast的工作方式提供了清晰的解释。好的,是的,这是有意义的,谢谢,我对reflector做了一点挖掘,它几乎无法辨认,但它确实暗示了你的解释,谢谢。@Ben:想象一下你正在构建一个类似CLR的运行时。您真的想在运行时嵌入C编程语言的绑定转换规则吗?如果VB/F/JScript/Perl/Ruby/C/C++/J/Python/。。。规则不同?为什么要在运行时对C规则进行特殊处理?因此,您在运行时获得的规则是最简单的最低公分母;只是一个型式试验。如果您想要编译时行为,可以使用C 4中的dynamic在运行时获取它,或者编写代码以便在编译时完成转换的解析。可能重复感谢您的输入,但我理解了原始答案。
Dim res = arrayOfStrings.Select(Function(__) CType( __, YourType ))