Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
270 views
in Technique[技术] by (71.8m points)

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

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 = (LinqToSQLType)MyLinq2SQLObj;

This works well.

However when you try to cast using the LINQ .Cast() extension method it trows an invalid cast exception saying cannot cast type Linq2SQLType to type DTOType. i.e. the below does not work

List<DTO.Name> Names = dbContact.tNames.Cast<DTO.Name>()
                                               .ToList();

But the below works fine:

DAL.tName MyDalName = new DAL.tName();
DTO.Name MyDTOName = (DTO.Name)MyDalName;

and the below also works fine

List<DTO.Name> Names = dbContact.tNames.Select(name => (DTO.Name)name)
                                               .ToList();

Why does the .Cast() extension method throw an invalid cast exception? I have used the .Cast() extension method in this way many times in the past and when you are casting something like a base type to a derived type it works fine, but falls over when the object has an explicit cast operator.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...