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 の Enum にバグがあり、バージョン 6.0 で修正されました。ImpromptuDictionary は、実行時に型を強制するいくつかの方法を試み、Enum に間違った方法を使用していました。だから今はうまくいく。

于 2012-08-03T18:54:41.693 に答える
0

問題は、Jsonシリアライザーが列挙型を数値としてシリアライズするという事実に起因すると思います。しかし、それを expando オブジェクトにデシリアライズすると、そのプロパティが実際に列挙型であることを認識できない可能性があります。これにより、expando オブジェクトの整数値が得られます。

これにより、即興インターフェイスが混乱し、プロキシのキャストで例外が発生します。これはここで解決できると思います.プロキシビルダーは、ターゲットタイプが列挙型であるかどうかをチェックし、 in から enum への作業カバーを使用します. ただし、公式ページに移動する必要があります。SOがこの問題を解決できるとは思わない。

于 2012-05-06T06:07:26.457 に答える