2012-05-06 36 views
2

考虑下面的代码:如何在使用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?) 
    } 
} 

是否有办法妥善解决这个问题呢?

回答

1

你行:

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

应该有工作但没有专门的ImpromptuInterface与枚举的错误,现在是fixed in version 6.0。 ImpromptuDictionary在运行时尝试了几种强制类型的方法,并且使用错误的Enums。所以它现在有效。

+0

6.0绝对修复了第一次失败的测试。第二次失败的测试现在失败,并显示以下错误:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:无法将类型'long'隐式转换为'Sandbox.ImpromptuInterfaceExample.Pet'。存在明确的转换(您是否缺少演员?)。这是否可以固定在您的目标上,或者这只是ActLike <>的不受支持的使用? –

+0

我发现将原始类型从ExpandoObject更改为ImpromptuDictionary会使两个测试都通过。谢谢你更新到6.0,Jay。 –

+0

是的ImpromptuDictionary做了上面的额外工作,并为转换做准备,单独由ActLike创建的接口代理期望结果匹配接口或者可以与implict转换。 – jbtule

0

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

然后这会混淆即兴接口并导致代理中的异常。我认为这可以在这里解决,代理构建器会检查,如果目标类型是枚举,并使用in inum的工作coverage。但你应该拿它to official page。我不认为SO可以解决这个问题。

+0

我同意你的评估。我给@JamesNK发了一封电子邮件,看看他是否计划向他的ExpandoObjectConverter添加TypeNameHandling支持。我认为这将解决这个问题,ImpromptuInterface可以做正确的事情。补丁10926(http://json.codeplex.com/SourceControl/list/patches)是“正在评估”,部分显然增加了这项功能。手指交叉... –