Parse a string to get a SectorId In mobile phones technologies, a SectorId is a 128-bit value broadcast by a 1xEV-DO BTS system.

That is a 16 bytes data.

I made a structure to store them:

using System;
using System.Globalization;
using System.Linq;
using System.Text;

public struct SectorId
{
    readonly byte[] id;

    SectorId(byte[] id)
    {
        this.id = new byte[16];
        Array.Copy(id, this.id, 16);
    }

    public override bool Equals(object obj)
    {
        if (obj is SectorId)
        {
            return Equals((SectorId)obj);
        }

        return false;
    }

    public bool Equals(SectorId other)
    {
        return id.SequenceEqual(other.id);
    }

    public override int GetHashCode()
    {
        int hash = 0;
        unchecked
        {
            foreach (var b in id)
            {
                hash *= 397;
                hash += b;
            }
        }
        return hash;
    }

    public static SectorId Parse(string s)
    {
        Throw.IfArgumentIsNull("s", s);

        SectorId result;
        if (TryParse(s, out result))
        {
            return result;
        }

        throw new FormatException();
    }

    public override string ToString()
    {
        var sb = new StringBuilder();
        foreach (var b in id)
        {
            sb.AppendFormat("{0:X2}", b);
        }
        return sb.ToString();
    }

    public static bool TryParse(string s, out SectorId result)
    {
        if (s == null)
        {
            goto Fail;
        }

        if (s.Length &gt; 32)
        {
            goto Fail;
        }

        if (s.Length &lt; 32)
        {
            s = s.PadRight(32, '0');    
        }

        var bytes = new byte[16];

        for (var i = 0; i &lt; 16; i++)
        {
            var substring = s.Substring(i * 2, 2);
            if (!byte.TryParse(substring, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out bytes[i]))
            {
                goto Fail;
            }
        }

        result = new SectorId(bytes);
        return true;

        Fail:
        result = default(SectorId);
        return false;
    }
}


The TryParse part is the worse for me. I would like to avoid gotos.
Note that you can use multiple return statements in a method, so instead of using goto, you can use a return statement. I.e:

if (s == null)
{
    return false;
}