1

注: .Net 4.0 の使用

次のコードを考えてみましょう。

String ad = "FE23658978541236";
String ad2 = "00FABE002563447E".ToLower();
try
{
    PhysicalAddress.Parse(ad);
}
catch (Exception)
{
    //We dont get here, all went well
}
try
{
    PhysicalAddress.Parse(ad2);
}
catch (Exception)
{
    //we arrive here for what reason?
}
try
{
    //Ok, I do it myself then.
    ulong dad2 = ulong.Parse(ad2, System.Globalization.NumberStyles.HexNumber);
    byte[] bad2 = BitConverter.GetBytes(dad2);
    if (BitConverter.IsLittleEndian)
    {
        bad2 = bad2.Reverse().ToArray<byte>();
    }
    PhysicalAddress pa = new PhysicalAddress(bad2);
}
catch (Exception ex)
{
    //We don't get here as all went well
}

そのため、小文字のアドレスを解析しようとすると、PhysicalAddress.Parse メソッドで例外がスローされます。.Net のソース コードを見ると、その理由は完全に明らかです。次のコードが原因です。

    if (value >= 0x30 && value <=0x39){ 
        value -= 0x30;
    } 
    else if (value >= 0x41 && value <= 0x46) {
        value -= 0x37;
    }

それはParseメソッド内にあります。

    public static PhysicalAddress Parse(string address) {
    int validCount = 0; 
    bool hasDashes = false; 
    byte[] buffer = null;

    if(address == null)
    {
        return PhysicalAddress.None;
    } 

    //has dashes? 
    if (address.IndexOf('-') >= 0 ){ 
        hasDashes = true;
        buffer = new byte[(address.Length+1)/3];    
    }
    else{

        if(address.Length % 2 > 0){  //should be even 
            throw new FormatException(SR.GetString(SR.net_bad_mac_address));
        } 

        buffer = new byte[address.Length/2];
    } 

    int j = 0;
    for (int i = 0; i < address.Length; i++ ) {

        int value = (int)address[i];

        if (value >= 0x30 && value <=0x39){ 
            value -= 0x30;
        } 
        else if (value >= 0x41 && value <= 0x46) {
            value -= 0x37;
        }
        else if (value == (int)'-'){ 
            if (validCount == 2) {
                validCount = 0; 
                continue; 
            }
            else{ 
                throw new FormatException(SR.GetString(SR.net_bad_mac_address));
            }
        }
        else{ 
            throw new FormatException(SR.GetString(SR.net_bad_mac_address));
        } 

        //we had too many characters after the last dash
        if(hasDashes && validCount >= 2){ 
            throw new FormatException(SR.GetString(SR.net_bad_mac_address));
        }

        if (validCount%2 == 0) { 
            buffer[j] = (byte) (value << 4);
        } 
        else{ 
            buffer[j++] |= (byte) value;
        } 

        validCount++;
    }

    //we too few characters after the last dash
    if(validCount < 2){ 
        throw new FormatException(SR.GetString(SR.net_bad_mac_address)); 
    }

    return new PhysicalAddress(buffer);
}

これはバグと見なすことができますか? それとも、文字列で小文字の 16 進数値を使用するのは非常に間違っているのでしょうか? または、私が知らない慣習があります。個人的には、このプログラマーは友好的ではないと考えています。

4

2 に答える 2

6

MSDNから:

address パラメーターには、数字と大文字の16 進数字のみで構成される文字列を含める必要があります。受け入れ可能な文字列形式の例をいくつか次に示します.... f0-e1-d2-c3-b4-a5 を含むアドレスは解析に失敗し、例外がスローされることに注意してください。

したがって、次のように簡単に実行できます。PhysicalAddress.Parse(ad.ToUpper());

于 2013-08-29T08:56:31.843 に答える
4

いいえ、ドキュメントに記載されていることを実行しない場合、またはドキュメントに記載されていないことを実行する場合、それは単なるバグです。期待どおりに動作しないという事実だけでは、バグにはなりません。もちろん、それは悪い設計上の決定 (または、雄弁に言えば、プログラマーに優しくない) と考えることができますが、それは同じことではありません。

私は「あなたが期待するものに寛容であり、あなたが提供するものに一貫性がある」という哲学に従うのが好きで、コードはおそらく次のようなもので簡単に修正できるので、あなたに同意する傾向があります。

if (value >= 0x30 && value <=0x39) { 
    value -= 0x30;
}
else if (value >= 0x41 && value <= 0x46) {
    value -= 0x37;
}
else if (value >= 0x61 && value <= 0x66) {  // added
    value -= 0x57;                          // added
}                                           // added
else if ...

ただし、もちろん、doco も変更する必要があり、膨大な数のテストを実行して、内容が詰め込まれていないことを確認する必要があります。

doco に関しては、ここで見つけることができ、重要な部分を以下に繰り返します (太字で示しています)。

address パラメーターには、数字と大文字の16 進数字のみで構成される文字列を含める必要があります。許容される文字列形式の例を次に示します。

001122334455
00-11-22-33-44-55
F0-E1-D2-C3-B4-A5

を含むアドレスはf0-e1-d2-c3-b4-a5 解析に失敗し、例外がスローされることに注意してください。

于 2013-08-29T08:58:22.693 に答える