【问题标题】:How do I resolve this enum cast issue when using ImpromptuInterface?使用 ImpromptuInterface 时如何解决此枚举转换问题?
【发布时间】:2012-05-06 05:26:31
【问题描述】:

给定以下代码:

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

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

【问题讨论】:

    标签: c#-4.0 dynamic json.net duck-typing impromptu-interface


    【解决方案1】:

    您的线路:

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

    应该可以工作,但是在 ImpromptuInterface 中存在 Enums 的错误,现在是 fixed in version 6.0。 ImpromptuDictionary 尝试了几种在运行时强制类型的方法,并且为 Enums 使用了错误的方法。所以现在可以了。

    【讨论】:

    • 6.0 确实修复了第一个失败的测试。第二个失败的测试现在失败并出现以下错误:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法将类型“long”隐式转换为“Sandbox.ImpromptuInterfaceExample.Pet”。存在显式转换(您是否缺少演员表?)。这是您可以解决的问题,还是仅仅是对 ActLike 的不支持使用?
    • 我发现将原始类型从 ExpandoObject 更改为 ImpromptuDictionary 可以使两个测试都通过。感谢您更新到 6.0,Jay。
    • 是的 ImpromptuDictionary 完成了额外的转换工作,ActLike 单独创建的接口代理期望结果与接口匹配或可以进行隐式转换。
    【解决方案2】:

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

    这会混淆即兴接口并导致转换代理异常。我认为这可以在这里解决,代理构建器将检查目标类型是否为枚举,并使用 in 到枚举的工作覆盖。但你应该接受它to official page。我不认为 SO 可以解决这个问题。

    【讨论】:

    • 我同意你的评价。我有一封电子邮件给@JamesNK,看看他是否计划将 TypeNameHandling 支持添加到他的 ExpandoObjectConverter。我认为这将解决 ImpromptuInterface 可以做正确事情的问题。补丁 10926 (json.codeplex.com/SourceControl/list/patches) 正在“被评估”,这在一定程度上显然增加了这个功能。手指交叉...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-31
    • 2011-10-02
    • 2021-09-03
    • 2020-03-12
    • 2020-08-24
    • 1970-01-01
    相关资源
    最近更新 更多