/// <summary> /// /// </summary> /// <param name="incomingType"></param> /// <param name="generateIncludedTypes"></param> /// <param name="destinationFolder"></param> /// <param name="forBiserBinary"></param> /// <param name="forBiserJson"></param> /// <param name="exclusions">excluded properties Names</param> /// <returns></returns> public static Dictionary <string, string> Run(Type incomingType, bool generateIncludedTypes, string destinationFolder, bool forBiserBinary = true, bool forBiserJson = true, HashSet <string> exclusions = null) { Dictionary <string, string> retT = new Dictionary <string, string>(); StandardTypes.InitDict(); JsonGenerator jg = new JsonGenerator(); BinaryGenerator bg = new BinaryGenerator(); HashSet <Type> typesToProcess = new HashSet <Type>(); HashSet <Type> typesProcessed = new HashSet <Type>(); typesToProcess.Add(incomingType); Type toProcess = null; if (exclusions == null) { exclusions = new HashSet <string>(); } if (!String.IsNullOrEmpty(destinationFolder) && !System.IO.Directory.Exists(destinationFolder)) { System.IO.Directory.CreateDirectory(destinationFolder); } while (true) { toProcess = typesToProcess.Where(r => !typesProcessed.Contains(r)).FirstOrDefault(); if (toProcess == null) { break; } string tmplIfcJson = ""; string tmplIfcBinary = ""; string contentJson = ""; string contentBinary = ""; if (forBiserJson) { tmplIfcJson = "Biser.IJsonEncoder"; contentJson = jg.Run(toProcess, exclusions); foreach (var el in jg.UsedObjects) { typesToProcess.Add(el); } } if (forBiserBinary) { tmplIfcBinary = " Biser.IEncoder"; contentBinary = bg.Run(toProcess, exclusions); foreach (var el in bg.UsedObjects) { typesToProcess.Add(el); } } string tmplIfcComma1 = (forBiserJson && forBiserBinary) ? "," : ""; var nsLen = toProcess.FullName.Length - toProcess.Name.Length - 1; var ret = Resource1.tmplBiserContainer.ReplaceMultiple( new Dictionary <string, string> { { "{@NamespaceName}", toProcess.FullName.Substring(0, nsLen) }, { "{@ObjName}", toProcess.Name }, { "{@IfcJson}", tmplIfcJson }, { "{@IfcBinary}", tmplIfcBinary }, { "{@IfcComma1}", tmplIfcComma1 }, { "{@ContentJson}", contentJson }, { "{@ContentBinary}", contentBinary } }); if (!String.IsNullOrEmpty(destinationFolder)) { //System.IO.File.WriteAllText(System.IO.Path.Combine(destinationFolder, toProcess.FullName + "_Biser.cs"), ret); System.IO.File.WriteAllText(System.IO.Path.Combine(destinationFolder, toProcess.Name + "_Biser.cs"), ret); //System.IO.File.WriteAllText(@"D:\Temp\1\TS6_Biser.cs", ret); } //retT.Add(incomingType.FullName + "_Biser.cs", ret); retT.Add(toProcess.FullName + "_Biser", ret); typesProcessed.Add(toProcess); if (!generateIncludedTypes) { break; } }//eo while return(retT); } //eof
/// <summary> /// /// </summary> /// <param name="iType"></param> /// <param name="sbJsonDecode"></param> /// <param name="varName"></param> /// <param name="varCnt"></param> /// <param name="mapper"></param> void DecodeSingle(Type iType, StringBuilder sbJsonDecode, string varName) { if (iType == typeof(byte[])) { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbJsonDecode.Append("\r\nvar "); } else { sbJsonDecode.Append("\r\n"); } sbJsonDecode.Append($"{varName} = "); if (StandardTypes.STypes.TryGetValue(iType, out var tf)) { sbJsonDecode.Append(tf.FGet); } sbJsonDecode.Append(";"); } else if (iType.IsArray) { StringBuilder msb1 = new StringBuilder(); StringBuilder msb2 = new StringBuilder(); StringBuilder msb3 = new StringBuilder(); var listType = typeof(List <>).MakeGenericType(iType.GetElementType()); if (iType.GetArrayRank() > 1) { var listType2 = typeof(Tuple <,>).MakeGenericType(typeof(List <int>), listType); varCntTotal++; int pv = varCntTotal; DecodeSingle(listType2, sbJsonDecode, $"pv{pv}"); //at this momemnt we can have Tuple //var pv1 = new Tuple<System.Collections.Generic.List<System.Int32>, System.Collections.Generic.List<System.Int32>>(pvar2, pvar5); for (int i = 0; i < iType.GetArrayRank(); i++) { if (i > 0) { msb1.Append(", "); } msb1.Append($"pv{pv}.Item1[{i}]"); } if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbJsonDecode.Append("\r\nvar "); } else { sbJsonDecode.Append("\r\n"); } int iof = 0; string strf = StandardTypes.GetFriendlyName(iType); StringBuilder revArr = new StringBuilder(); for (int j = strf.Length - 1; j >= 0; j--) { var l = strf[j]; if (l == '[' || l == ']' || l == ',') { iof++; if (l == '[') { l = ']'; } else if (l == ']') { l = '['; } revArr.Append(l); } else { break; } } var revArrStr = revArr.ToString(); revArrStr = revArrStr.Substring(revArrStr.IndexOf("]") + 1); if (iof > 0) { strf = $"{strf.Substring(0, strf.Length - iof)}[{msb1.ToString()}]{revArrStr.ToString()}"; } else { strf = $"{strf}[{msb1.ToString()}]"; } sbJsonDecode.Append($"{varName} = new {strf};"); varCntTotal++; int arenm = varCntTotal; sbJsonDecode.Append($"\r\nvar arenm{arenm} = pv{pv}.Item2.GetEnumerator();"); sbJsonDecode.Append($"\r\narenm{arenm}.MoveNext();"); varCntTotal++; int ardpv = varCntTotal; for (int i = 0; i < iType.GetArrayRank(); i++) { if (i > 0) { msb3.Append(", "); } msb3.Append($"ard{ardpv}_{i}"); if (i == iType.GetArrayRank() - 1) {//last element msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++) {{"); msb2.Append($"\r\n{varName}[{msb3.ToString()}] = arenm{arenm}.Current;"); msb2.Append($"\r\narenm{arenm}.MoveNext();"); msb2.Append($"\r\n}}"); } else { msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++)"); } } sbJsonDecode.Append(msb2.ToString()); } else { //Reading List to prepare transformation Dictionary <int, string> varmap = new Dictionary <int, string>(); for (int i = 0; i < iType.GetArrayRank(); i++) { // var listType = typeof(List<>).MakeGenericType(iType.GetElementType()); varCntTotal++; varmap.Add(i, $"intlst{varCntTotal}"); DecodeSingle(listType, sbJsonDecode, $"intlst{varCntTotal}"); } //sbJsonDecode.Append("\r\n//------------------"); if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbJsonDecode.Append("\r\nvar "); } else { sbJsonDecode.Append("\r\n"); } for (int i = 0; i < iType.GetArrayRank(); i++) { if (i > 0) { msb1.Append(", "); msb3.Append(", "); } varCntTotal++; int ardpv = varCntTotal; msb1.Append($"{varmap[i]}.Count"); msb3.Append($"ard{ardpv}_{i}"); //--- if (i == iType.GetArrayRank() - 1) {//last element msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++) {{"); //msb2.Append($"\r\n{varName}[ard{ardpv}_{i}] = {varmap[i]}[ard{ardpv}_{i}];"); msb2.Append($"\r\n{varName}[{msb3.ToString()}] = {varmap[i]}[ard{ardpv}_{i}];"); msb2.Append($"\r\n}}"); } else { msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++)"); } } int iof = 0; string strf = StandardTypes.GetFriendlyName(iType); StringBuilder revArr = new StringBuilder(); for (int j = strf.Length - 1; j >= 0; j--) { var l = strf[j]; if (l == '[' || l == ']' || l == ',') { iof++; if (l == '[') { l = ']'; } else if (l == ']') { l = '['; } revArr.Append(l); } else { break; } } var revArrStr = revArr.ToString(); revArrStr = revArrStr.Substring(revArrStr.IndexOf("]") + 1); if (iof > 0) { strf = $"{strf.Substring(0, strf.Length - iof)}[{msb1.ToString()}]{revArrStr.ToString()}"; } else { strf = $"{strf}[{msb1.ToString()}]"; } sbJsonDecode.Append($"{varName} = decoder.CheckNull() ? null : new {strf};"); sbJsonDecode.Append($"\r\nif({varName} != null){{"); sbJsonDecode.Append($"{msb2.ToString()}"); sbJsonDecode.Append($"\r\n}}"); } } else if (iType.GetInterface("ICollection`1") != null) { StringBuilder msb = new StringBuilder(); if (iType.GetInterface("ISet`1") != null || iType.GetInterface("IList`1") != null) { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = decoder.CheckNull() ? null : new {StandardTypes.GetFriendlyName(iType)}();"); msb.Append($"\r\nif({varName} != null){{"); varCntTotal++; int pv1 = varCntTotal; msb.Append($"\r\n\tforeach(var el{pv1} in decoder.GetList()) {{"); StringBuilder sbi = new StringBuilder(); varCntTotal++; int pv2 = varCntTotal; DecodeSingle(iType.GenericTypeArguments[0], sbi, $"pvar{pv2}"); msb.Append(sbi.ToString()); msb.Append($"\r\n\t\t{varName}.Add(pvar{pv2});"); msb.Append($"\r\n\t}}"); msb.Append($"\r\n}}"); //eof if varname != null sbJsonDecode.Append(msb.ToString()); } else if (iType.GetInterface("IDictionary`2") != null) { var kT = iType.GenericTypeArguments[0]; if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = decoder.CheckNull() ? null : new {StandardTypes.GetFriendlyName(iType)}();"); msb.Append($"\r\nif({varName} != null){{"); varCntTotal++; int pv1 = varCntTotal; msb.Append($"\r\n\tforeach(var el{pv1} in decoder.GetDictionary<{kT}>()) {{"); StringBuilder sbi = new StringBuilder(); varCntTotal++; int pv2 = varCntTotal; DecodeSingle(iType.GenericTypeArguments[1], sbi, $"pvar{pv2}"); msb.Append(sbi.ToString()); msb.Append($"\r\n\t\t{varName}.Add(el{pv1}, pvar{pv2});"); msb.Append($"\r\n\t}}"); msb.Append($"\r\n}}"); //eof if varname != null sbJsonDecode.Append(msb.ToString()); } } else if (iType.GetInterface("ITuple") != null) { Dictionary <int, Type> dTuple = new Dictionary <int, Type>(); StringBuilder sbi = new StringBuilder(); StringBuilder msb = new StringBuilder(); bool first = true; StringBuilder tupleType = new StringBuilder(); List <string> tuplSbi = new List <string>(); foreach (var gta in iType.GetGenericArguments()) { sbi.Clear(); varCntTotal++; int ka = varCntTotal; dTuple.Add(varCntTotal, gta); UsedVars.Add($"pvar{varCntTotal}"); DecodeSingle(gta, sbi, $"pvar{varCntTotal}"); if (first) { first = false; } else { tupleType.Append(", "); } tupleType.Append(StandardTypes.GetFriendlyName(gta)); var defaultValue = StandardTypes.GetDefaultValue(gta); if (defaultValue == null) { defaultValue = $"default({StandardTypes.GetFriendlyName(gta)})"; } msb.Append($"\r\n{StandardTypes.GetFriendlyName(gta)} pvar{ka} = {defaultValue};"); //varCnt = varCntNew; tuplSbi.Add(sbi.ToString()); } varCntTotal++; msb.Append($"\r\nforeach (var tupleProps{varCntTotal} in decoder.GetDictionary<string>()){{"); msb.Append($"\r\nswitch(tupleProps{varCntTotal}){{"); int elcnt = 0; foreach (var el in tuplSbi) { elcnt++; msb.Append($"\r\ncase \"Item{elcnt}\":"); msb.Append(el); msb.Append($"\r\nbreak;"); } msb.Append("\r\n}}"); if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = new Tuple<{tupleType.ToString()}>("); first = true; foreach (var el in dTuple) { if (first) { first = false; } else { msb.Append(", "); } msb.Append($"pvar{el.Key}"); } msb.Append(");"); sbJsonDecode.Append(msb.ToString()); } else if (iType.IsEnum) { //var nullableEnum = Nullable.GetUnderlyingType(iType); Type underlyingType = Enum.GetUnderlyingType(iType); if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbJsonDecode.Append("\r\nvar "); } else { sbJsonDecode.Append("\r\n"); } sbJsonDecode.Append($"{varName} = ({iType.Name})"); if (StandardTypes.STypes.TryGetValue(underlyingType, out var tf)) { sbJsonDecode.Append(tf.FGet); } else { throw new Exception("Enum.GetUnderlyingType generation has failed"); } sbJsonDecode.Append(";"); } else { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbJsonDecode.Append("\r\nvar "); } else { sbJsonDecode.Append("\r\n"); } sbJsonDecode.Append($"{varName} = "); if (StandardTypes.STypes.TryGetValue(iType, out var tf)) { sbJsonDecode.Append(tf.FGet); } else { if (iType == myType) { throw new Exception("Cross-Reference exception. Object can't contain itself as a property"); } //adding object to UsedObjects list UsedObjects.Add(iType); sbJsonDecode.Append(StandardTypes.GetFriendlyName(iType) + ".BiserJsonDecode(null, decoder)"); } sbJsonDecode.Append(";"); } //return varCntTotal; }
/// <summary> /// /// </summary> /// <param name="iType"></param> /// <param name="sbDecode"></param> /// <param name="varName"></param> /// <param name="varCnt"></param> int DecodeSingle(Type iType, StringBuilder sbDecode, string varName) { if (iType == typeof(byte[])) { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbDecode.Append("\r\nvar "); } else { sbDecode.Append("\r\n"); } sbDecode.Append($"{varName} = "); if (StandardTypes.STypes.TryGetValue(iType, out var tf)) { sbDecode.Append(tf.FGet); } sbDecode.Append(";"); } else if (iType.IsArray) { StringBuilder msb1 = new StringBuilder(); StringBuilder msb2 = new StringBuilder(); StringBuilder msb3 = new StringBuilder(); if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbDecode.Append("\r\nvar "); } else { sbDecode.Append("\r\n"); } for (int i = 0; i < iType.GetArrayRank(); i++) { if (i > 0) { msb1.Append(", "); msb3.Append(", "); } varCntTotal++; int ardpv = varCntTotal; msb1.Append("decoder.GetInt()"); msb3.Append($"ard{ardpv}_{i}"); //--- if (i == iType.GetArrayRank() - 1) {//last element msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++) {{"); varCntTotal++; UsedVars.Add($"{varName}[{msb3.ToString()}]"); DecodeSingle(iType.GetElementType(), msb2, $"{varName}[{msb3.ToString()}]"); msb2.Append($"\r\n}}"); } else { msb2.Append($"\r\nfor(int ard{ardpv}_{i} = 0; ard{ardpv}_{i} < {varName}.GetLength({i}); ard{ardpv}_{i}++)"); } } int iof = 0; string strf = StandardTypes.GetFriendlyName(iType); StringBuilder revArr = new StringBuilder(); for (int j = strf.Length - 1; j >= 0; j--) { var l = strf[j]; if (l == '[' || l == ']' || l == ',') { iof++; if (l == '[') { l = ']'; } else if (l == ']') { l = '['; } revArr.Append(l); } else { break; } } var revArrStr = revArr.ToString(); revArrStr = revArrStr.Substring(revArrStr.IndexOf("]") + 1); if (iof > 0) { strf = $"{strf.Substring(0, strf.Length - iof)}[{msb1.ToString()}]{revArrStr.ToString()}"; } else { strf = $"{strf}[{msb1.ToString()}]"; } sbDecode.Append($"{varName} = decoder.CheckNull() ? null : new {strf};"); sbDecode.Append($"\r\nif({varName} != null){{"); sbDecode.Append($"{msb2.ToString()}"); sbDecode.Append($"\r\n}}"); } else if (iType.GetInterface("ICollection`1") != null) { StringBuilder msb = new StringBuilder(); if (iType.GetInterface("ISet`1") != null || iType.GetInterface("IList`1") != null) { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = decoder.CheckNull() ? null : new {StandardTypes.GetFriendlyName(iType)}();"); msb.Append($"\r\nif({varName} != null){{"); msb.Append($"\r\n\tdecoder.GetCollection(() => {{"); StringBuilder sbi = new StringBuilder(); varCntTotal++; int pv2 = varCntTotal; DecodeSingle(iType.GenericTypeArguments[0], sbi, $"pvar{pv2}"); msb.Append(sbi.ToString()); msb.Append($"\r\n\t\treturn pvar{pv2};"); msb.Append($"\r\n\t}}, {varName}, true);"); msb.Append($"\r\n}}"); sbDecode.Append(msb.ToString()); } else if (iType.GetInterface("IDictionary`2") != null) { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = decoder.CheckNull() ? null : new {StandardTypes.GetFriendlyName(iType)}();"); msb.Append($"\r\nif({varName} != null){{"); msb.Append($"\r\n\tdecoder.GetCollection(() => {{"); StringBuilder sbi = new StringBuilder(); varCntTotal++; int pv2 = varCntTotal; DecodeSingle(iType.GenericTypeArguments[0], sbi, $"pvar{pv2}"); msb.Append(sbi.ToString()); msb.Append($"\r\n\t\treturn pvar{pv2};"); msb.Append($"\r\n}},"); msb.Append($"\r\n() => {{"); sbi.Clear(); varCntTotal++; int pv3 = varCntTotal; DecodeSingle(iType.GenericTypeArguments[1], sbi, $"pvar{pv3}"); msb.Append(sbi.ToString()); msb.Append($"\r\n\t\treturn pvar{pv3};"); msb.Append($"\r\n\t}}, {varName}, true);"); msb.Append($"\r\n}}"); sbDecode.Append(msb.ToString()); } } else if (iType.GetInterface("ITuple") != null) { Dictionary <int, Type> dTuple = new Dictionary <int, Type>(); StringBuilder sbi = new StringBuilder(); StringBuilder msb = new StringBuilder(); bool first = true; StringBuilder tupleType = new StringBuilder(); List <string> tuplSbi = new List <string>(); foreach (var gta in iType.GetGenericArguments()) { sbi.Clear(); varCntTotal++; int kv = varCntTotal; dTuple.Add(varCntTotal, gta); UsedVars.Add($"pvar{varCntTotal}"); DecodeSingle(gta, sbi, $"pvar{varCntTotal}"); if (first) { first = false; } else { tupleType.Append(", "); } tupleType.Append(StandardTypes.GetFriendlyName(gta)); var defaultValue = StandardTypes.GetDefaultValue(gta); if (defaultValue == null) { defaultValue = $"default({StandardTypes.GetFriendlyName(gta)})"; } msb.Append($"\r\n{StandardTypes.GetFriendlyName(gta)} pvar{kv} = {defaultValue};"); tuplSbi.Add(sbi.ToString()); } int elcnt = 0; foreach (var el in tuplSbi) { elcnt++; msb.Append(el); } if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); msb.Append("\r\nvar "); } else { msb.Append("\r\n"); } msb.Append($"{varName} = new Tuple<{tupleType.ToString()}>("); first = true; foreach (var el in dTuple) { if (first) { first = false; } else { msb.Append(", "); } msb.Append($"pvar{el.Key}"); } msb.Append(");"); sbDecode.Append(msb.ToString()); } else if (iType.IsEnum) { //var nullableEnum = Nullable.GetUnderlyingType(iType); Type underlyingType = Enum.GetUnderlyingType(iType); if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbDecode.Append("\r\nvar "); } else { sbDecode.Append("\r\n"); } sbDecode.Append($"{varName} = ({iType.Name})"); if (StandardTypes.STypes.TryGetValue(underlyingType, out var tf)) { sbDecode.Append(tf.FGet); } else { throw new Exception("Enum.GetUnderlyingType generation has failed"); } sbDecode.Append(";"); } else { if (!UsedVars.Contains(varName)) { UsedVars.Add(varName); sbDecode.Append("\r\nvar "); } else { sbDecode.Append("\r\n"); } sbDecode.Append($"{varName} = "); if (StandardTypes.STypes.TryGetValue(iType, out var tf)) { sbDecode.Append(tf.FGet); } else { if (iType == myType) { throw new Exception("Cross-Reference exception. Object can't contain itself as a property"); } UsedObjects.Add(iType); sbDecode.Append(StandardTypes.GetFriendlyName(iType) + ".BiserDecode(null, decoder)"); } sbDecode.Append(";"); } return(varCntTotal); }
void EncodeSingle(Type iType, StringBuilder sbJsonEncode, string varName, bool root) { //List<string> endings = new List<string>(); if (iType.IsArray) { if (iType == typeof(byte[])) { if (root) { sbJsonEncode.Append($"\r\nencoder.Add(\"{varName}\", {varName});"); } else { sbJsonEncode.Append($"\r\nencoder.Add({varName});"); } } else { sbJsonEncode.Append($"if({varName} != null) {{"); if (iType.GetArrayRank() > 1) { //Multi-dimensional arrays will be represented as a Tuple, where first element is a List<int> containing dimensions //and second element is a sequence of an array elements. //--------------check array null conditions varCntTotal++; int pvard = varCntTotal; sbJsonEncode.Append($"\r\nvar arrdim{pvard}=new System.Collections.Generic.List<int>();"); for (int i = 0; i < iType.GetArrayRank(); i++) { sbJsonEncode.Append($"\r\narrdim{pvard}.Add({varName}.GetLength({i}));"); } var listType1 = typeof(List <>).MakeGenericType(typeof(int)); varCntTotal++; int pv = varCntTotal; StringBuilder msb = new StringBuilder(); var listType = typeof(List <>).MakeGenericType(iType.GetElementType()); sbJsonEncode.Append($"\r\n{StandardTypes.GetFriendlyName(listType)} r{pv}= new {StandardTypes.GetFriendlyName(listType)}();"); sbJsonEncode.Append($"\r\nforeach(var el in {varName})"); sbJsonEncode.Append($"\r\nr{pv}.Add(el);"); varCntTotal++; int pvtpl = varCntTotal; var listType2 = typeof(Tuple <,>).MakeGenericType(typeof(List <int>), listType); sbJsonEncode.Append($"\r\nvar r{pvtpl} = new Tuple<System.Collections.Generic.List<int>, {StandardTypes.GetFriendlyName(listType)}>(arrdim{pvard}, r{pv});"); EncodeSingle(listType2, msb, $"r{pvtpl}", root); msb.Replace($"\"r{pvtpl}\"", $"\"{varName}\""); sbJsonEncode.Append(msb.ToString()); } else {//one dimensional or jagged array varCntTotal++; int pv = varCntTotal; StringBuilder msb = new StringBuilder(); sbJsonEncode.Append($"\r\nvar r{varCntTotal}={varName}.ToList();"); var listType = typeof(List <>).MakeGenericType(iType.GetElementType()); EncodeSingle(listType, msb, $"r{pv}", root); msb.Replace($"\"r{pv}\"", $"\"{varName}\""); sbJsonEncode.Append(msb.ToString()); } sbJsonEncode.Append($"}}"); } } else if (iType.GetInterface("ICollection`1") != null) { if (root) { sbJsonEncode.Append($"\r\nencoder.Add(\"{varName}\", {varName}"); } else { sbJsonEncode.Append($"\r\nencoder.Add({varName}"); } if (iType.GetInterface("ISet`1") != null || iType.GetInterface("IList`1") != null) { varCntTotal++; sbJsonEncode.Append($", (r{varCntTotal}) => {{"); EncodeSingle(iType.GenericTypeArguments[0], sbJsonEncode, "r" + varCntTotal, false); sbJsonEncode.Append($"}});"); } else if (iType.GetInterface("IDictionary`2") != null) { varCntTotal++; sbJsonEncode.Append($", (r{varCntTotal}) => {{"); EncodeSingle(iType.GenericTypeArguments[1], sbJsonEncode, "r" + varCntTotal + "", false); sbJsonEncode.Append($"}});"); } } else if (iType.GetInterface("ITuple") != null) { if (root) { sbJsonEncode.Append($"\r\nencoder.Add(\"{varName}\", "); } else { sbJsonEncode.Append($"\r\nencoder.Add("); } sbJsonEncode.Append($"({varName} == null) ? new Dictionary<string,Action>() : new Dictionary<string, Action>() {{"); int tn = 1; foreach (var gta in iType.GetGenericArguments()) { sbJsonEncode.Append($"{((tn==1)?"":", ")}{{ \"Item{tn}\", () => {{"); EncodeSingle(gta, sbJsonEncode, $"{varName}.Item{tn}", false); sbJsonEncode.Append($"}}}}"); tn++; } sbJsonEncode.Append($"}});"); } else if (iType.IsEnum) { //var nullableEnum = Nullable.GetUnderlyingType(iType); Type underlyingType = Enum.GetUnderlyingType(iType); // sbJsonEncode.Append($"\r\nencoder.Add(({underlyingType.ToString()}){varName});"); if (root) { sbJsonEncode.Append($"\r\nencoder.Add(\"{varName}\", ({underlyingType.ToString()}){varName});"); } else { sbJsonEncode.Append($"\r\nencoder.Add(({underlyingType.ToString()}){varName});"); } } else { if (root) { sbJsonEncode.Append($"\r\nencoder.Add(\"{varName}\", {varName});"); } else { sbJsonEncode.Append($"\r\nencoder.Add({varName});"); } } }