网上已经有很多JSON的反序列化的代码了,但自以为自己能写出更好的,所以就写了一个这方面的东西.实现的思路是,先把JSON字符串分析成JSON结点树,再根据传进来的实体的类型从结点树上取内容.
核心算法如下:

构建分析树#region 构建分析树
private Tree<JSONNode> ReadTokens(char[] jsonChars)

{
Tree<JSONNode> rootNode = new Tree<JSONNode>();
TreeNode<JSONNode> currentNode = rootNode;
int curPos = 0;
int index = 0;
bool isKey = false;

NextLoop:

while (index < jsonChars.Length)

{
switch (jsonChars[index])

{

字符串#region 字符串
case '"':

{
index++;
curPos = index;

while (index < jsonChars.Length)

{
if (jsonChars[index].Equals('"'))

{
if (!jsonChars[index - 1].Equals('\\'))

{
if (curPos < index - 1)

{
JSONNode node = new JSONNode(JSONTokenId.StringLiteral ,curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
}

index++;
break;
}
else

{
int p = index - 1;


while (p > curPos && jsonChars[p].Equals('\\'))
{ p--; }

if ((index - p) % 2 == 1)

{
if (curPos < index - 1)

{
JSONNode node = new JSONNode(JSONTokenId.StringLiteral,curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
}

index++;
break;
}
}
}

index++;
}

break;
}
#endregion
case '{':

{
index++;
JSONNode node = new JSONNode(JSONTokenId.ObjectLiteral);
currentNode = currentNode.AddChild(node);
isKey = true;
break;
}
case '[':

{
index++;
JSONNode node = new JSONNode(JSONTokenId.ArrayLiteral);
currentNode = currentNode.AddChild(node);
break;
}
case ']':

{
index++;
currentNode = currentNode.Parent;
break;
}
case '}':

{
index++;
currentNode = currentNode.Parent.Parent;
isKey = false;
break;
}
case ':':

{
index++;
if (currentNode.Parent.Content != null && currentNode.Parent.Content.TokenId == JSONTokenId.ObjectLiteral)

{
isKey = false;
}
break;
}
case ',':

{
index++;
if (currentNode.Parent.Content !=null && currentNode.Parent.Content.TokenId == JSONTokenId.ObjectLiteral)

{
isKey = true;
currentNode = currentNode.Parent;
}
break;
}

数字#region 数字
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':

{
curPos = index;

JSONTokenId numKind = JSONTokenId.IntLiteral;
bool isReal = false;

if (jsonChars[index].Equals('.'))

{
index++;

if (index < jsonChars.Length && (jsonChars[index] >= '0' && jsonChars[index] <= '9'))

{
numKind = JSONTokenId.RealLiteral;
isReal = true;
}
}

bool isNum = true;
if (index < jsonChars.Length && jsonChars[index].Equals('0'))

{
index++;

if (index < jsonChars.Length && (jsonChars[index].Equals('x') || jsonChars[index].Equals('X')))

{
isNum = true;

index++;

while (index < jsonChars.Length && isNum)

{
switch (jsonChars[index])

{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':

{
index++;
break;
}
default:

{
isNum = false;
break;
}
}
}

if (index < jsonChars.Length && (jsonChars[index].Equals('l') || jsonChars[index].Equals('L')))

{
index++;
numKind = JSONTokenId.LongLiteral;

if (index < jsonChars.Length && (jsonChars[index].Equals('u') || jsonChars[index].Equals('U')))

{
index++;
numKind = JSONTokenId.ULongLiteral;
}
}
else if (index < jsonChars.Length && (jsonChars[index].Equals('u') || jsonChars[index].Equals('U')))

{
index++;
numKind = JSONTokenId.UIntLiteral;

if (index < jsonChars.Length && (jsonChars[index].Equals('l') || jsonChars[index].Equals('L')))

{
index++;
numKind = JSONTokenId.ULongLiteral;
}
}

JSONNode node = new JSONNode(numKind, curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
break;
}
}

isNum = true;

while (index < jsonChars.Length && isNum)

{
switch (jsonChars[index])

{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':

{
index++;
break;
}
case '.':

{
if (isReal)

{
numKind = JSONTokenId.RealLiteral;
JSONNode node = new JSONNode(numKind, curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
goto NextLoop;
}

index++;

if (index < jsonChars.Length && (jsonChars[index] < '0' || jsonChars[index] > '9'))

{
JSONNode node = new JSONNode(numKind, curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
goto NextLoop;
}
else

{
numKind = JSONTokenId.RealLiteral;
isReal = true;
}
index++;
break;
}
default:

{
isNum = false;
break;
}
}
}

if (index < jsonChars.Length)

{
if (jsonChars[index].Equals('e') || jsonChars[index].Equals('E'))

{
index++;
numKind = JSONTokenId.RealLiteral;

if (index < jsonChars.Length && (jsonChars[index].Equals('+') || jsonChars[index].Equals('-')))

{
index++;
}

isNum = true;
while (index < jsonChars.Length && isNum)

{
switch (jsonChars[index])

{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':

{
index++;
break;
}
default:

{
isNum = false;
break;
}
}
}

}
else if (jsonChars[index].Equals('d') || jsonChars[index].Equals('D') ||
jsonChars[index].Equals('f') || jsonChars[index].Equals('F') ||
jsonChars[index].Equals('m') || jsonChars[index].Equals('M')
)

{
index++;
numKind = JSONTokenId.RealLiteral;
}
else if (jsonChars[index].Equals('l') || jsonChars[index].Equals('L'))

{
index++;
numKind = JSONTokenId.LongLiteral;

if (index < jsonChars.Length && (jsonChars[index].Equals('u') || jsonChars[index].Equals('U')))

{
index++;
numKind = JSONTokenId.ULongLiteral;
}
}
else if (jsonChars[index].Equals('u') || jsonChars[index].Equals('U'))

{
index++;
numKind = JSONTokenId.UIntLiteral;

if (index < jsonChars.Length && (jsonChars[index].Equals('l') || jsonChars[index].Equals('L')))

{
index++;
numKind = JSONTokenId.ULongLiteral;
}
}
}

JSONNode numNode = new JSONNode(numKind, curPos, index);
if (isKey)

{
currentNode = currentNode.AddChild(numNode);
}
else

{
currentNode.AddChild(numNode);
}
break;
}
#endregion
default:

{

关键词#region 关键词
switch (jsonChars[index])

{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':

{
curPos = index;
index++;

bool endIdent = false;

while (index < jsonChars.Length && !endIdent)

{
switch (jsonChars[index])

{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':

{
index++;
break;
}
default:

{
endIdent = true;
break;
}
}
}
if (curPos < index)

{
JSONNode node = new JSONNode(JSONTokenId.StringLiteral,curPos, index);

if (isKey)

{
currentNode = currentNode.AddChild(node);
}
else

{
currentNode.AddChild(node);
}
}
break;
}
default:

{
index++;
break;
}
}
#endregion
break;
}
}
}

return rootNode;
}
#endregion