1

私は YAML を使用して C# GUI とサーバー側 Java の間で通信していますが、これは一般的に正常に動作しています。ただし、Double であるフィールドを渡し、値が Java 側で Double.NaN の場合、Yaml は ".NaN" として渡され、C# 側で逆シリアル化すると、C# として「System.FormatException」がスローされます。文字列 "NaN" [".NaN" ではない] が必要です。

デシリアライザーをインターセプトする方法があるかどうか、または C# 側で ".NaN" を double で解析できるようにフォーマットを追加する方法があるかどうかは誰にもわかりませんか?

(私が考えることができる 1 つの回避策は、YAML にシリアライズする前にすべての NaN を特別な値に変更し、次に C# で特別な値を認識して NaN に変換することですが、これは大きなハックのようです。)

4

1 に答える 1

0

これは、YamlDotNet がフロートを処理する方法のバグのようです。INodeDeserializer修正されるまでは、これらの特殊なケースを処理するカスタム ノードを登録することで回避できます。

以下は、そのようなデシリアライザーの簡単な実装です。

public class FloatNodeDeserializer : INodeDeserializer
{
    private static readonly Dictionary<Tuple<Type, string>, object> SpecialFloats =
        new Dictionary<Tuple<Type, string>, object>
    {
        { Tuple.Create(typeof(float), ".nan"), float.NaN },
        { Tuple.Create(typeof(float), ".inf"), float.PositiveInfinity },
        { Tuple.Create(typeof(float), "-.inf"), float.NegativeInfinity },

        { Tuple.Create(typeof(double), ".nan"), double.NaN },
        { Tuple.Create(typeof(double), ".inf"), double.PositiveInfinity },
        { Tuple.Create(typeof(double), "-.inf"), double.NegativeInfinity },
    };

    bool INodeDeserializer.Deserialize(
        EventReader reader,
        Type expectedType,
        Func<EventReader, Type, object> nestedObjectDeserializer,
        out object value
    ) {
        var scalar = reader.Peek<Scalar>();
        if (scalar == null) {
            value = null;
            return false;
        }

        var found = SpecialFloats.TryGetValue(
            Tuple.Create(expectedType, scalar.Value),
            out value);

        if(found) {
            reader.Allow<Scalar>();
        }
        return found;
    }
}

登録方法は次のとおりです。

var deserializer = new Deserializer();
deserializer.NodeDeserializers.Insert(0, new FloatNodeDeserializer());

ここで完全に機能するフィドルを参照してください

于 2015-09-24T12:56:00.317 に答える