문제

Given the following code:

public enum Pet
{
    Cat,
    Dog
}

public interface IOwner
{
    Pet Pet
    {
        get;
        set;
    }
}

public class Owner : IOwner
{
    public Pet Pet
    {
        get;
        set;
    }
}

The following tests fail:

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

Is there a way to properly resolve this problem?

도움이 되었습니까?

해결책

Your line:

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

Should have worked but there was a bug with Enums specifically in ImpromptuInterface that is now fixed in version 6.0. ImpromptuDictionary tries several ways to coerce a type at runtime and was using the wrong one for Enums. So it works now.

다른 팁

I think, the problem stems from fact, that Json serialiser serialises enums as numbers. But when it deserialises it into expando object, then it cannot possibly know, that the property is actualy an enum. This results in integer value in expando object.

This then confuses the impromptu-interface and causes exception in casting proxy. I think this could be resolved here, that the proxy builder would check, if the target type is enum, and use working coversion of in into enum. But you should take it to official page. I don't think SO can solve this problem.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top