2012-09-10 79 views
6

從D2007轉換爲XE2,我轉換該功能如何設置類型爲TEncoding的函數參數的默認值?

function Add_Line(FileStream : TFileStream; ALine : string) : boolean; 

function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean; 
var 
    AStr: ANSISTring; 
begin 
    Result := True; 
    if Enc = nil then Enc := TEncoding.ANSI; 
    try 
//Old FileStream.WriteBuffer(Pointer(ALine)^, Length(ALine)); 
    if Enc = TEncoding.UTF8 then 
     AStr := UTF8Encode(ALine) 
    else 
     AStr := ANSIString(ALine); 
    FileStream.WriteBuffer(AStr[1], Length(ALine)); 
    end; 
    except 
    Result := False; 
    end; 
end; 

理由:使用Add_Line儘可能少

    • 更改代碼接受自動更改爲Unic ode,只在最後時刻寫入8位文本文件(這在XML和CSV中使用)。如果我們願意,將來我們仍然可以轉移到UTF-16文件。

    我本來定義是這樣的:

    function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = TEncoding.ANSI) : boolean; 
    

    但是編譯器會抱怨;-)

    就像是可能的東西嗎?

  • +2

    默認參數限制爲常量值是我總是贊成使用重載的一個原因。 –

    +0

    超負荷從來沒有超過我的想法;-) –

    回答

    12

    默認參數必須是一個編譯時間常數,但如果你有什麼需要更高級的,你可以創建重載:

    function Add_Line(FileStream : TFileStream; ALine : string) : boolean; overload; 
    function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding) : boolean; overload; 
    
    
    function Add_Line(FileStream : TFileStream; ALine : string) : boolean; 
    begin 
        Result := Add_Line(FileStream, ALine, TEncoding.ANSI); 
    end; 
    

    你甚至可以添加inline關鍵字得到完全相同的生成代碼的默認的論據會導致,如果它是有效的。

    注意:除了TEncoding.ANSITEncoding.UTF8之外,您似乎不支持其他任何內容。在這種情況下,TEncoding參數看起來有些過分,您可以使用UTF8: Boolean參數(或重寫代碼以使用任意編碼的CodePage)。

    注2:FileStream.WriteBuffer(AStr[1], Length(ALine));是錯誤的,因爲Length(ALine)Length(AStr)不需要相同,您應該使用Length(AStr)來代替。另外,當AStr爲空字符串時,AStr[1]可能會導致異常,您可以添加特殊情況僅在AStr非空時才調用WriteBuffer

    +0

    爲了將來的使用,我會給它一個TEncoding參數,並感謝指出長度()錯字!可能會導致可怕的數據;-) –

    5

    其他人已評論如何指定TEncoding參數的默認值。我想指出,你使用TEncoding是完全錯誤的一般。

    TEncoding.UTF8並不是獲得UTF-8編碼對象(TEncoding.GetEncoding(65001)是另一種方式)的唯一方法,因此檢查TEncoding.UTF8具體是錯誤的。更糟糕的是,你完全忽略了任何非UTF8編碼,而只是編碼其他符合普通的AnsiString,這完全違背了使用TEncoding的全部目的。例如,用戶可以傳遞ISO-8859-X編碼對象,並且您的輸出不會像用戶請求的那樣進行ISO編碼。你不妨改變你的參數爲UseUTF8: Boolean = False參數,而不是,因爲那是你如何有效地使用它:

    function Add_Line(FileStream : TFileStream; ALine : string; UseUTF8: Boolean = False) : boolean; 
    var 
        AStr: AnsiString; 
    begin 
        Result := True; 
        try 
        if UseUTF8 then 
         AStr := UTF8Encode(ALine) 
        else 
         AStr := AnsiString(ALine); 
        if AStr <> '' then 
         FileStream.WriteBuffer(AStr[1], Length(AStr)); 
        except 
        Result := False; 
        end; 
    end; 
    

    使用TEncoding是讓它做實際的編碼正確的方法,不要做編碼自己:

    function Add_Line(FileStream : TFileStream; ALine : string; Enc: TEncoding = nil) : boolean; 
    var 
        AStr: TBytes; 
    begin 
        if ALine = '' then 
        begin 
        Result := True; 
        Exit; 
        end; 
        Result := False; 
        try 
        if Enc = nil then Enc := TEncoding.Ansi; 
        AStr := Enc.GetBytes(ALine); 
        // GetBytes() returns 0 bytes if it fails to encode, it does not raise an exception! 
        if Length(AStr) = 0 then Exit; 
        FileStream.WriteBuffer(AStr[0], Length(AStr)) 
        except 
        Exit; 
        end; 
        Result := True; 
    end; 
    
    相關問題