「System」ユニットのLength関数にStringを引き渡す場合のみ
「Unit1」ユニットに新しく作成したLength関数を呼ばせたい。
string : Lehgth ⇒ Unit1.Lehgth
配列他 : Lehgth ⇒ System.Lehgth
参照ユニット(uses)でUnit1を指定した所
stringも配列他も全て「Unit1」へ参照してしまうため
引数の型がエラーとなってしまします。
上記のようなユニットを跨ったoverloadのような事は可能でしょうか?
もう少し詳しく説明してください。意味がわかりません。
このような一般的な関数名をUnitの関数に使うのはやめましょう。バグのもとです。
>string : Lehgth ⇒ Unit1.Lehgth
>配列他 : Lehgth ⇒ System.Lehgth
var
Tmp: Integer;
Str: String;
Ary: array[0..2] of Integer;
begin
//Stringの場合
Str := 'ABC';
Tmp := Unit1.Length(Str);
//配列の場合
Tmp := System.Length(Ary);
のように配列の場合、単にLengthとするのではなくSystem.Lengthとすれば良いのでは、と。
※この場合StringはUnit1.Lengthではなく単にLengthとしてもOKですが、Unit1.Lengthとした方がSystemのLengthではなくUnit1のLengthを使用していると読み取れるので良いかと。
OVERLOAD 付けてためしたか?
たとえば
function IntToStr(Value,Length: Integer;C: Char = '0'):String;
var
S : String;
begin
if Length <= 0 then
begin
Result := IntToStr(Value);
end
else
begin
S := StringOfChar(C,Length);
S := S + IntToStr(Value);
Result := Copy(S,System.Length(S)-Length+1,Length);
end;
end;
な感じで パラメータが異なるやつならば Overload すれば可能
(SysUtils.IntToStr と共存可能)
----------
function Length(Value: String): Integer;
begin
Result := System.Length(Value);
end;
にしてしまうと
Stringのみで DynamicArray に対応できなくなる (今回の話)
function Length(Value: String): Integer; overload;
begin
Result := System.Length(Value);
end;
function Length(Value: array of Byte): Integer; overload;
begin
Result := System.Length(Value);
end;
function Length(Value: array of Char): Integer; overload;
begin
Result := System.Length(Value);
end;
で個別に作ると
System.Length と 同じパラメータになるでの
呼び出しがあいまいと怒られる
自作 Length のパラメータが System.Length と異なるならば
Overload すれば共存可能
>自作 Length のパラメータが System.Length と異なるならば
>Overload すれば共存可能
なので、型を認識させればとりあえずはコンパイルできるようですが、String以外を一本の関数にまとめる方法は分かりません。
手間をかけてLengthを自作するより、関数名の変更を推奨します...
ちなみに、下記サンプルは、'再宣言された識別子'の警告(XE2の場合)が出ますが、
TArray<型>を手抜きせずに宣言すれば警告は消えると思います。
var
str1: String;
iarr: TArray<Integer>;
farr: TArray<Double>;
function Length(S: String): SmallInt; overload;
begin
Result := System.Length(S)*2;
end;
function Length(Arr: TArray<Integer>): SmallInt; overload;
begin
Result := System.Length(Arr);
end;
function Length(Arr: TArray<Double>): SmallInt; overload;
begin
Result := System.Length(Arr);
end;
begin
str1 := 'hoge';
SetLength(iarr, 3);
SetLength(farr, 2);
ShowMessage(Format('%d, %d, %d', [Length(str1), Length(iarr), Length(farr)])); // '8, 3, 2'
SetLength(iarr, 0);
SetLength(farr, 0);
end.
ご意見有難うございました。
以下の対応で場合分けする事で対応できました。
//Stringの場合(Unit1.Length)
Tmp := Length(Str);
//配列の場合(System.Length)
Tmp := System.Length(Ary);
元々Length等の共通関数にどうしても割り込みを入れなくては
ならなくなってしまったのですが
対象箇所が多すぎるために「system」から別のユニットの同名関数を参照出来ないか考えていました。
引数「String」のみ必要であったためそれ以外は「system」を参照させようと拘り過ぎていたようです。
幸い「System.」と手を入れる箇所自体少ない上、コンパイルエラーから場所特定が簡単でした。
根本解決ではありませんがベターな方法がとれそうです。
以上有難うございました。
System.Length と 同じパラメータになるでの
呼び出しがあいまいと怒られる
これは自作Lengthも別ユニットにした場合だけだった
ツイート | ![]() |