Cast.Cast<int?> applied on generic enum collection results in invalid cast exception

前端 未结 2 498
情书的邮戳
情书的邮戳 2021-01-12 13:11
enum Gender { Male, Female }

var k = new[] { Gender.Male }.Cast().ToList().Cast().ToList(); //alright

var p = new[] { Gender.Male }.Cast<         


        
相关标签:
2条回答
  • 2021-01-12 13:30

    Ok I have come to find out the cause, which is still strange. I should have checked up Cast<T> implementation myself first of all!

    This is how Cast<T> is implemented:

    public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)
    {
        IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
        if (enumerable != null)
        {
            return enumerable; // this is the culprit..
        }
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        return Enumerable.CastIterator<TResult>(source);
    }
    
    private static IEnumerable<TResult> CastIterator<TResult>(IEnumerable source)
    {
        foreach (object current in source)
        {
            yield return (TResult)((object)current);
        }
        yield break;
    }
    

    Now the problem is with the first Cast<int> call:

    new[] { Gender.Male }.Cast<int>()
    

    Here source as IEnumerable<TResult> where source is new[] { Gender.Male } and TResult is int in the generic method returns a non null value (which basically means (new[] { Gender.Male } is an IEnumerable<int> in generic context), and hence it returns the same enumerable back which is Gender[], and in the next Cast<int?> call, the actual cast is performed, which is from Gender to int? which fails. As to why this happens in generic context, catch it in this question.

    0 讨论(0)
  • 2021-01-12 13:34

    This is due to deferred execution. The latter statement actually tries to cast Gender.Male to int?. In contrast, the first statement actually performs the cast operation to an int and gets a List<int> before deferring the execution to cast those to int?; clearly int to int? has an implicity conversion defined already.

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