LINQ .Cast() extension method fails but (type)object works

前端 未结 3 1974
南笙
南笙 2020-12-14 18:42

To convert between some LINQ to SQL objects and DTOs we have created explicit cast operators on the DTOs. That way we can do the following:

DTOType MyDTO =          


        
相关标签:
3条回答
  • 2020-12-14 19:02

    For those that hit this question looking for a workaround...

    Dim res = arrayOfStrings.Select(Function(__) CType( __, YourType ))
    

    Not sure the exact semantics with C#, but i'm sure it's pretty easy.

    0 讨论(0)
  • 2020-12-14 19:10

    If you decompile the Linq assembly you get code resembling the following. The previous answer is correct, ultimately the cast is from 'object' to target-type which will always fail for custom types.

    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

    0 讨论(0)
  • 2020-12-14 19:11

    The Cast<> extension method does not apply user-defined conversions. It can only cast to interfaces or within the class heirarchy of the supplied type.

    User defined conversions are identified at compile time based on the static types involved in the expression. They cannot be applied as runtime conversions, so the following is illegal:

    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
    

    It doesn't matter whether a UDC exists from SomeType to OtherType - it cannot be applied through a reference of type object. Trying to run the above code would fail at runtime, reporting something like:

    System.InvalidCastException: 
        Unable to cast object of type 'SomeType' to type 'OtherType'
    

    Cast<>() can only perform representation preserving conversions ... that's why you can't use it to apply user-defined conversions.

    Eric Lippert has a great article about the behavior of the cast operator in C# - always a worthwhile read.

    0 讨论(0)
提交回复
热议问题