Generics: casting and value types, why is this illegal?

后端 未结 3 813
太阳男子
太阳男子 2020-11-29 09:46

Why is this a compile time error?

public TCastTo CastMe(TSource i)
{
     return (TCastTo)i;
}

Error:

3条回答
  •  青春惊慌失措
    2020-11-29 10:24

    C# uses one cast syntax for multiple different underlying operations:

    • upcast
    • downcast
    • boxing
    • unboxing
    • numeric conversion
    • user-defined conversion

    In generic context, the compiler has no way of knowing which of those is correct, and they all generate different MSIL, so it bails out.

    By writing return (TCastTo)(object)i; instead, you force the compiler to do an upcast to object, followed by a downcast to TCastTo. The compiler will generate code, but if that wasn't the right way to convert the types in question, you'll get a runtime error.


    Code Sample:

    public static class DefaultConverter
    {
        private static Converter cached;
    
        static DefaultConverter()
        {
            ParameterExpression p = Expression.Parameter(typeof(TSource));
            cached = Expression.Lambda(Expression.Convert(p, typeof(TCastTo), p).Compile();
        }
    
        public static Converter Instance { return cached; }
    }
    
    public static class DefaultConverter
    {
         public static TOutput ConvertBen(TInput from) { return DefaultConverter.Instance.Invoke(from); }
         public static TOutput ConvertEric(dynamic from) { return from; }
    }
    

    Eric's way sure is shorter, but I think mine should be faster.

提交回复
热议问题