2009-09-04 56 views
4

首先讓我解釋一下我目前是如何處理的驗證,也就是說,對於IPv4地址:我知道我在做驗證錯誤。請說服我停止:)

public struct IPv4Address { 
    private string value; 

    private IPv4Address(string value) { 
     this.value = value; 
    } 

    private static IPv4Address CheckSyntax(string value) { 
     // If everything's fine... 
     return new IPv4Address(value); 

     // If something's wrong with the syntax... 
     throw new ApplicationException("message"); 
    } 

    public static implicit operator IPv4Address(string value) { 
     return CheckSyntax(value); 
    } 

    public static implicit operator string(IPv4Address address) { 
     return address.value; 
    } 
} 

我有一堆像這樣的結構的。

他們經常有額外的私人成員來處理事情,但不公開暴露方法。

下面是一個簡單的用法:

IPv4Address a; 
IPv4Address b = "1.2.3.4"; 
a = b; 
b = "5.6.7.8"; 

string address = a; 

// c contains "1.2.3.4" 
IPv4Address c = address; 

// See if it's valid 
try { 
    IPv4Address d = "111.222.333.444"; 
} 
catch (ApplicationException e) { 
    // Handle the exception... 
} 

我能感覺到有什麼東西非常令人不安的這個問題,所以我琢磨一下與像IsIPv4Address方法等切換到靜態類。

現在,這裏就是我認爲是錯誤的與上面的方法:

  • 新的團隊成員將不得不環繞此

  • 他們的頭它可能會妨礙與第三方代碼集成

  • 異常昂貴

  • 從未見過這樣的事情,我是一個保守的ative類型的心臟:)

然後呢我喜歡它:

  • 非常接近有很多專門的原語,因爲你有值類型。

  • 實際上,它們可以像基本類型那樣經常使用,例如,它不是將上述結構傳遞給接受字符串的方法的問題。

  • 而且,我最喜歡的是,您可以在對象之間傳遞這些結構,並確保它們包含語法上有效的值。這也避免了必須經常檢查正確性,如果不必要地甚至遺忘,這可能是昂貴的。

我無法找到上述方法的致命缺陷(這裏只是一個初學者),您怎麼看?

編輯:正如你可以從第一行推斷這只是一個例子,我沒有要求一種方法來驗證IP地址。

+1

是什麼毛病System.Net.IPAddress? – Joey 2009-09-04 14:56:04

+1

@Johannes:我想他很想知道,如果有什麼,他的驗證架構是錯誤的,而不是這個特定的方法。 – Beska 2009-09-04 14:56:55

+0

難道你不能只使用inet_aton(來自unix http://linux.about.com/library/cmd/blcmdl3_inet_aton.htm)?在你的平臺上應該有一個相同的東西。 請確保支持IPv6地址;) – tonfa 2009-09-04 15:00:28

回答

4

首先,您應該閱讀關於隱式投射的文章,以及何時使用它(以及爲什麼在您的場景中使用它不好),您可以開始here
如果你需要有檢查方法,他們應該是公開的,而不是這種奇怪的結構靜,這旁邊,有這樣的方法可以讓你通過返回一些選擇,如果你想拋出異常(如.Parse()方法做),或信號應該檢查的值(如.TryParse()方法)。
除此之外,如果您真的想要創建有效對象的靜態方法並不意味着您不能使用值類型(結構)而不是類。此外,請記住結構具有隱含的空構造函數,你不能「躲」,因此,即使你的構造可以像這樣使用:

IPv4Address a = new IPv4Address();

,這將給你無效的結構(值爲null)。

+0

這是一個很好的答案,我選擇了亞伯拉罕的一個,因爲它更完整。 儘管如此,可惜很多回答的人都沒有仔細閱讀這個問題。 – RobSullivan 2009-09-04 16:37:45

+0

我已經想通了,如果你想分析IP地址,你會爲谷歌準備好的解決方案,你會立即發現,所以我專注於編程模式的一部分你的問題,我很高興,這是什麼你正在尋找。 – 2009-09-04 16:49:42

4

我也很喜歡模仿框架的基本模式,所以我會按照通過朝IpV4Address.Parse("1.2.3.4")(與TryParse一起)傾斜,而不是隱式轉換的概念。

0

似乎有很多複雜性,沒有任何好處。只因爲你可以不意味着你應該。

取而代之的是CheckSyntax(字符串值),返回一個IP(此方法順便說一句措辭不當),我只是碰到這樣一個

bool IsIP(string) 

然後,你可以把它放進一個工具類,或基類,或者某個地方的單獨抽象。

0

MSDN topic on implicit conversions

預定義的隱式轉換 總是成功,並不會引起 拋出異常。正確 設計的用戶自定義隱式轉換 應該表現出這些 特點以及

微軟本身並沒有始終遵循這一建議。下面使用System.Xml.Linq.XName的隱式操作,將引發XmlException:

XName xname = ":"; 

System.Xml.Linq也許設計師用它逃走了由not documenting異常:-)

相關問題