给定以下代码:
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?)
}
}
有没有办法正确解决这个问题?
你的行:
var duckType = ImpromptuDictionary.Create<IOwner>(dynamicOwner);
应该可以工作,但是 Enums 有一个错误,特别是在 ImpromptuInterface 中,现在已经在 6.0 版中修复了。ImpromptuDictionary尝试了几种在运行时强制类型的方法,并且对枚举使用了错误的方法。所以它现在有效。
,问题源于事实,即 Json 序列化器将枚举序列化为数字。但是当它将其反序列化为 expando 对象时,它不可能知道该属性实际上是一个枚举。这会导致 expando 对象中的整数值。
然后,这会混淆即兴接口并导致强制转换代理异常。我认为这可以在这里解决,代理构建器将检查目标类型是否为枚举,并使用 in 到枚举的工作转换。但是您应该将其带到官方页面。我不认为SO可以解决这个问题。