注意:使用.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);
}
这可以被视为错误吗?或者在字符串中使用较低的套接字十六进制值是非常错误的?或者是否有一些我不知道的惯例。 就个人而言,我认为这个程序员不友好。
答案 0 :(得分:6)
来自MSDN:
address参数必须包含只能包含的字符串 数字和大写字母为十六进制数字。一些例子 可接受的字符串格式如下....请注意,包含f0-e1-d2-c3-b4-a5的地址将无法解析并抛出异常。
所以你可以这样做:PhysicalAddress.Parse(ad.ToUpper());
答案 1 :(得分: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,可以找到它here,重要的一点在下面重复(用我的粗体):
address参数必须包含一个字符串,该字符串只能包含数字,大写字母包含十六进制数字。可接受的字符串格式的一些示例如下:
001122334455
00-11-22-33-44-55
F0-E1-D2-C3-B4-A5
请注意,包含
f0-e1-d2-c3-b4-a5
的地址无法解析并引发异常。