Как мне решить эту проблему при использовании ImpromptuInterface?
Учитывая следующий код:
public enum Pet
{
Cat,
Dog
}
public interface IOwner
{
Pet Pet
{
get;
set;
}
}
public class Owner : IOwner
{
public Pet Pet
{
get;
set;
}
}
Следующие тесты не пройдены:
[TestFixture]
public class ImpromptuInterfaceExample
{
private Owner owner;
private ExpandoObject dynamicOwner;
[SetUp]
public void SetUp()
{
owner = new Owner { Pet = Pet.Dog };
string serializedOwner = JsonConvert.SerializeObject(owner);
dynamicOwner = JsonConvert.DeserializeObject<ExpandoObject>(serializedOwner);
}
[Test]
public void InvalidCastException()
{
var duckType = ImpromptuDictionary.Create<IOwner>(dynamicOwner);
Assert.That(duckType.Pet, Is.EqualTo(owner.Pet)); // System.InvalidCastException : Invalid cast from 'System.Int64' to 'JsonSerializationDemo.Pet'.
}
[Test]
public void RuntimeBinderException()
{
var duckType = dynamicOwner.ActLike<IOwner>();
Assert.That(duckType.Pet, Is.EqualTo(owner.Pet)); // Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : Cannot implicitly convert type 'long' to 'JsonSerializationDemo.Pet'. An explicit conversion exists (are you missing a cast?)
}
}
Есть ли способ правильно решить эту проблему?
2 ответа
Ваша линия:
var duckType = ImpromptuDictionary.Create<IOwner>(dynamicOwner);
Должно было сработать, но была ошибка с Enums, особенно в ImpromptuInterface, которая теперь исправлена в версии 6.0. ImpromptuDictionary пытается несколькими способами привести тип во время выполнения и использует неправильный для Enums. Так что теперь это работает.
Я думаю, проблема связана с тем, что сериализатор Json сериализует перечисления как числа. Но когда он десериализует его в объект расширения, то он не может знать, что это свойство действительно является перечислением. Это приводит к целочисленному значению в объекте expando.
Это затем сбивает с толку импровизированный интерфейс и вызывает исключение при использовании прокси. Я думаю, что здесь можно решить, что прокси-сборщик проверит, является ли целевой тип enum, и использует рабочее покрытие in в enum. Но вы должны перейти на официальную страницу. Я не думаю, что ТАК может решить эту проблему.