Last active
May 17, 2018 13:46
-
-
Save neuecc/161fe0ae68cbb3ea1f2ccb6db84d8504 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// AutomataDictionaryを使う&むしろType無視してIValueだけで済ましてしまうパターン(こら | |
// reader.ReadObjectSegment/ReadArraySegmentがあって、小ブロックを取得できるようにすれば解決しそう(追加します | |
public class Container | |
{ | |
public string Type { get; set; } | |
public IValue Value { get; set; } | |
} | |
[JsonFormatter(typeof(InterfaceFormatter))] | |
public interface IValue | |
{ | |
} | |
public class InterfaceFormatter : IJsonFormatter<IValue> | |
{ | |
static readonly AutomataDictionary automata = new AutomataDictionary(); | |
static InterfaceFormatter() | |
{ | |
automata.Add("Foo", 0); | |
automata.Add("Hoge", 1); | |
} | |
public IValue Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) | |
{ | |
if (reader.ReadIsNull()) return null; | |
var count = 0; | |
IValue result = null; | |
while (reader.ReadIsInObject(ref count)) | |
{ | |
var propName = reader.ReadPropertyNameSegmentRaw(); | |
var i = -1; | |
automata.TryGetValue(propName, out i); | |
switch (i) | |
{ | |
case 0: | |
result = new ValueTypeA { Foo = reader.ReadInt32() }; | |
break; | |
case 1: | |
result = new ValueTypeB { Hoge = reader.ReadString() }; | |
break; | |
default: | |
reader.ReadNextBlock(); | |
break; | |
} | |
} | |
return result; | |
} | |
public void Serialize(ref JsonWriter writer, IValue value, IJsonFormatterResolver formatterResolver) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
public class ValueTypeA : IValue | |
{ | |
public int Foo { get; set; } | |
} | |
public class ValueTypeB : IValue | |
{ | |
public string Hoge { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var json = @" | |
{ | |
""Type"": ""TypeA"", | |
""Value"": { | |
""Foo"": 10 | |
} | |
} | |
"; | |
JsonSerializer.Deserialize<Container>(json).Dump(); | |
json = @" | |
{ | |
""Value"": { | |
""Hoge"": ""mogemoge"" | |
}, | |
""Type"": ""TypeB"" | |
} | |
"; | |
JsonSerializer.Deserialize<Container>(json).Dump(); | |
var container = JsonSerializer.Deserialize<Container>(json); | |
if (container.Type == "TypeA") | |
{ | |
var value = (ValueTypeA)container.Value; | |
value.Foo.Dump(); | |
} | |
else if (container.Type == "TypeB") | |
{ | |
var value = (ValueTypeB)container.Value; | |
value.Hoge.Dump(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// dynamic使えばJSON.NET likeですよパターン | |
[JsonFormatter(typeof(ContainerFormatter))] | |
public class Container | |
{ | |
public string Type { get; set; } | |
public IValue Value { get; set; } | |
public class ContainerFormatter : IJsonFormatter<Container> | |
{ | |
public Container Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver) | |
{ | |
if (reader.ReadIsNull()) return null; | |
var obj = formatterResolver.GetFormatterWithVerify<dynamic>().Deserialize(ref reader, formatterResolver); | |
var type = obj["Type"] as string; | |
var value = (type == "TypeA") ? new ValueTypeA { Foo = (int)obj["Value"]["Foo"] } | |
: (type == "TypeB") ? new ValueTypeB { Hoge = (string)obj["Value"]["Hoge"] } | |
: (IValue)null; | |
return new Container() | |
{ | |
Type = type, | |
Value = value | |
}; | |
} | |
public void Serialize(ref JsonWriter writer, Container value, IJsonFormatterResolver formatterResolver) | |
{ | |
throw new NotImplementedException(); | |
} | |
} | |
} | |
public interface IValue | |
{ | |
} | |
public class ValueTypeA : IValue | |
{ | |
public int Foo { get; set; } | |
} | |
public class ValueTypeB : IValue | |
{ | |
public string Hoge { get; set; } | |
} | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var json = @" | |
{ | |
""Type"": ""TypeA"", | |
""Value"": { | |
""Foo"": 10 | |
} | |
} | |
"; | |
JsonSerializer.Deserialize<Container>(json).Dump(); | |
json = @" | |
{ | |
""Value"": { | |
""Hoge"": ""mogemoge"" | |
}, | |
""Type"": ""TypeB"" | |
} | |
"; | |
JsonSerializer.Deserialize<Container>(json).Dump(); | |
var container = JsonSerializer.Deserialize<Container>(json); | |
if (container.Type == "TypeA") | |
{ | |
var value = (ValueTypeA)container.Value; | |
value.Foo.Dump(); | |
} | |
else if (container.Type == "TypeB") | |
{ | |
var value = (ValueTypeB)container.Value; | |
value.Hoge.Dump(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment