Delphi 如何为TEncoding类型的函数参数设置默认值?

Delphi 如何为TEncoding类型的函数参数设置默认值?,delphi,unicode,encoding,delphi-xe2,Delphi,Unicode,Encoding,Delphi Xe2,从D2007转换到XE2,我转换了这个函数 function Add_Line( FileStream : TFileStream; ALine : string) : boolean; 到 理由: 尽可能少地使用Add_行更改代码 接受对Unicode的自动更改,仅在最后一刻写入8位文本文件(这在XML和CSV中使用)。将来,如果我们愿意,我们仍然可以使用UTF-16文件 我想定义如下: function Add_Line( FileStream : TFileStream; ALine

从D2007转换到XE2,我转换了这个函数

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

理由:

  • 尽可能少地使用Add_行更改代码

  • 接受对Unicode的自动更改,仅在最后一刻写入8位文本文件(这在XML和CSV中使用)。将来,如果我们愿意,我们仍然可以使用UTF-16文件

我想定义如下:

function Add_Line( FileStream : TFileStream; ALine : string; Enc: TEncoding = TEncoding.ANSI) : boolean;
但是编译器抱怨;-)


可以这样做吗?

默认参数必须是编译时常量,但如果需要更高级的参数,可以创建重载:

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.ANSI
TEncoding.UTF8
。在这种情况下,
TEncoding
参数似乎有些过分,您可以改用
UTF8:Boolean
参数(或者重新编写代码以使用任意编码的
代码页


注2:
FileStream.WriteBuffer(AStr[1],长度(ALine))
是错误的,因为
Length(ALine)
Length(AStr)
不必相同,您应该使用
Length(AStr)
。另外,
AStr[1]
AStr
为空字符串时可能导致异常,您可以添加一个特殊情况,仅在
AStr
不为空时调用
WriteBuffer

其他人对如何为
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参数,谢谢你指出Length()的拼写错误!可能导致可怕的数据;-)
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;  
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;