Pregunta

Para acortar una larga historia:. I utiliza el reflector de la clase System.Security.Util.Tokenizer, y hay un montón de Goto declaraciones allí

He aquí un fragmento breve ejemplo:

    Label_0026:
        if (this._inSavedCharacter != -1)
        {
            num = this._inSavedCharacter;
            this._inSavedCharacter = -1;
        }
        else
        {
            switch (this._inTokenSource)
            {
                case TokenSource.UnicodeByteArray:
                    if ((this._inIndex + 1) < this._inSize)
                    {
                        break;
                    }
                    stream.AddToken(-1);
                    return;

                case TokenSource.UTF8ByteArray:
                    if (this._inIndex < this._inSize)
                    {
                        goto Label_00CF;
                    }
                    stream.AddToken(-1);
                    return;

                case TokenSource.ASCIIByteArray:
                    if (this._inIndex < this._inSize)
                    {
                        goto Label_023C;
                    }
                    stream.AddToken(-1);
                    return;

                case TokenSource.CharArray:
                    if (this._inIndex < this._inSize)
                    {
                        goto Label_0272;
                    }
                    stream.AddToken(-1);
                    return;

                case TokenSource.String:
                    if (this._inIndex < this._inSize)
                    {
                        goto Label_02A8;
                    }
                    stream.AddToken(-1);
                    return;

                case TokenSource.NestedStrings:
                    if (this._inNestedSize == 0)
                    {
                        goto Label_030D;
                    }
                    if (this._inNestedIndex >= this._inNestedSize)
                    {
                        goto Label_0306;
                    }
                    num = this._inNestedString[this._inNestedIndex++];
                    goto Label_0402;

                default:
                    num = this._inTokenReader.Read();
                    if (num == -1)
                    {
                        stream.AddToken(-1);
                        return;
                    }
                    goto Label_0402;
            }
            num = (this._inBytes[this._inIndex + 1] << 8) + this._inBytes[this._inIndex];
            this._inIndex += 2;
        }
        goto Label_0402;
    Label_00CF:
        num = this._inBytes[this._inIndex++];
        if ((num & 0x80) != 0)
        {
            switch (((num & 240) >> 4))
            {
                case 8:
                case 9:
                case 10:
                case 11:
                    throw new XmlSyntaxException(this.LineNo);

                case 12:
                case 13:
                    num &= 0x1f;
                    num3 = 2;
                    break;

                case 14:
                    num &= 15;
                    num3 = 3;
                    break;

                case 15:
                    throw new XmlSyntaxException(this.LineNo);
            }
            if (this._inIndex >= this._inSize)
            {
                throw new XmlSyntaxException(this.LineNo, Environment.GetResourceString("XMLSyntax_UnexpectedEndOfFile"));
            }
            byte num2 = this._inBytes[this._inIndex++];
            if ((num2 & 0xc0) != 0x80)
            {
                throw new XmlSyntaxException(this.LineNo);
            }
            num = (num << 6) | (num2 & 0x3f);
            if (num3 != 2)
            {
                if (this._inIndex >= this._inSize)
                {
                    throw new XmlSyntaxException(this.LineNo, Environment.GetResourceString("XMLSyntax_UnexpectedEndOfFile"));
                }
                num2 = this._inBytes[this._inIndex++];
                if ((num2 & 0xc0) != 0x80)
                {
                    throw new XmlSyntaxException(this.LineNo);
                }
                num = (num << 6) | (num2 & 0x3f);
            }
        }
        goto Label_0402;
    Label_023C:
        num = this._inBytes[this._inIndex++];
        goto Label_0402;
    Label_0272:
        num = this._inChars[this._inIndex++];
        goto Label_0402;
    Label_02A8:
        num = this._inString[this._inIndex++];
        goto Label_0402;
    Label_0306:
        this._inNestedSize = 0;

Me esencialmente quería saber cómo funcionaba la clase, pero el número de Goto de hace imposible. Podría decirse algo parecido a las necesidades de la clase Tokenizer a ser muy optimizado, por lo que mi pregunta es: ¿se Reflector hacerlo mal, o es goto una optimización para esta clase

¿Fue útil?

Solución

Parece que el reflector es incapaz de determinar la estructura de bucle originales.

Como un punto de interés (y por qué esto es a veces el caso) no son códigos de operación para cosas como IL while y bucles for y break y continue. La IL equivalente es pruebas if sólo combinados con saltos (es decir GOTOS).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top