2

给定以下代码:

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?)
    }
}

有没有办法正确解决这个问题?

4

2 回答 2

1

您的线路:

 var duckType = ImpromptuDictionary.Create<IOwner>(dynamicOwner);

应该可以工作,但是在 ImpromptuInterface 中特别是 Enums 存在一个错误,现在已在 6.0 版中修复。ImpromptuDictionary 尝试了几种在运行时强制类型的方法,并且为 Enums 使用了错误的方法。所以它现在有效。

于 2012-08-03T18:54:41.693 回答
0

我认为,问题源于事实,即 Json 序列化器将枚举序列化为数字。但是当它将它反序列化为 expando 对象时,它不可能知道该属性实际上是一个枚举。这会在 expando 对象中产生整数值。

然后,这会混淆即兴界面并导致铸造代理异常。我认为这可以在这里解决,代理构建器将检查目标类型是否为枚举,并使用 in 到枚举的工作覆盖。但是你应该把它带到官方页面。我不认为SO可以解决这个问题。

于 2012-05-06T06:07:26.457 回答