Почему динамический параметр в обобщенном методе генерирует исключение нулевой ссылки при использовании объекта?

Интересно, может ли кто-нибудь объяснить, почему в этом коде

public class SomeClass
{
    public T GenericMethod<T>(dynamic value)
    {
        return (T)value;
    }
}

"возвращаемое значение"; оператор выдает исключение нулевой ссылки при вызове с помощью:

new SomeClass().GenericMethod<object>(new object()); // throws System.NullReferenceException

Он работает, как ожидается, при вызове с помощью:

new SomeClass().GenericMethod<string>("SomeString"); // returns SomeString
new SomeClass().GenericMethod<object>("SomeString"); // returns SomeString

Примечание: Следующий компилируется и работает просто отлично

public class SomeOtherClass
{
    public T GenericMethod<T>(object value)
    {
        return (T)value;
    }
}

Элемент stacktrace:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.GenerateLambda(EXPRCALL pExpr)
   at Microsoft.CSharp.RuntimeBinder.Semantics.ExprVisitorBase.Visit(EXPR pExpr)
   at Microsoft.CSharp.RuntimeBinder.ExpressionTreeCallRewriter.Rewrite(TypeManager typeManager, EXPR pExpr, IEnumerable`1 listOfParameters)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
   at Microsoft.CSharp.RuntimeBinder.CSharpConvertBinder.FallbackConvert(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
   at System.Dynamic.DynamicMetaObject.BindConvert(ConvertBinder binder)
   at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
   at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)

Ответ 2

Обновление

Поскольку отмеченный дубликат указывает, что это известная ошибка в среде выполнения .NET.


Проблема, вероятно, является плохой индикацией недействительного исполнения во время выполнения. Если вы выберете динамическое связывание и введите тип параметра object, вы получите ошибку компилятора

Невозможно неявно преобразовать тип 'object' в 'T'. Явное преобразование существует (вы пропускаете листинг?)

Так как, добавив dynamic, это кастинг выполняется во время выполнения, эта неявная ошибка преобразования проявляется по-разному во время выполнения с неопределенным NullReferenceException в привязках времени выполнения.

Я не эксперт в области внутренней работы DLR, но я подозреваю, что объект, прошедший как значение dynamic, на самом деле не является чистым object во время выполнения. Я подозреваю, что это какая-то обертка вокруг object и, следовательно, не может быть неявно передана объекту во время выполнения.

Явная ссылка

return (T)(object)value;

не будет генерировать эту ошибку.