Следующий код вызывает исключение. TryConvert не вызывается для приведения к интерфейсу. Почему это? Можно ли обойти эту проблему?
using System.Dynamic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
dynamic test = new JsonNull();
var ok = (string)test;
// Next line throws:
// Unable to cast object of type 'ConsoleApplication1.JsonNull' to type 'ConsoleApplication1.IFoo'.
var fail = (IFoo)test;
}
}
class JsonNull : DynamicObject
{
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = null;
return !binder.Type.IsValueType;
}
}
interface IFoo { }
}
Я подозреваю, что это потому, что в C # (и, возможно, .NET в целом) вы не можете создать определяемое пользователем преобразование в тип интерфейса (точно так же, как вы не можете создать определяемое пользователем преобразование в / из базового / дочернего типа). Поэтому каждое преобразование интерфейса рассматривается как преобразование в рамку или как эталонное преобразование.
Это на самом деле - всего лишь предположение.
РЕДАКТИРОВАТЬ: С другой стороны, я только что взглянул на код, сгенерированный для:
dynamic d = ...;
IDisposable x = (IDisposable) d;
, и он действительно генерирует динамический вызов через Binder.Convert
, так что это делает не компилятор C #. Хм.