「参照渡し」は悪い設計ですか?
一般的ではありません。特定のシナリオを理解し、関数が何をするのか自問する必要があります。また、特に他の人のためにコーディングしている (ライブラリを配布している) 場合は、コーディング スタイルを適切に定義する必要があります。
関数が複数の出力を返す場合、参照渡しは通常有効です。ResultContainer
関数が返すすべての情報を含むオブジェクトを返すことをお勧めします。次の C# の例を見てください。
bool isTokenValid(string token, out string username)
VS
AuthenticationResult isTokenValid(string token)
class AuthenticationResult {
public bool AuthenticationResult;
public string Username;
}
違いは、参照 (この場合out
は put) パラメーターを持つメソッドは、トークンの検証またはオプションでユーザー情報を抽出するためにのみ使用できることを明確に強調していることです。したがって、パラメーターを渡す義務がある場合でも、必要がなければ破棄できます。2 番目の例は、より詳細なコードです。
もちろん、そのような方法がある場合は、2番目のデザインが望ましいです
bool doSomething(object a, ref object b, ref object c, ref object d, ... ref object z);
それらすべてをコンテナにラップするからです。
ここで明確にしましょう。Java と C# では、非プリミティブ型は常に cloned reference として渡されます。つまり、object
s 自体は複製されませんが、それらへの参照のみがスタックに複製されるため、返された後にまったく異なるオブジェクトを指すことは期待できません。代わりに、オブジェクトの状態がメソッドによって変更されることを常に期待しています。それ以外の場合はclone()
、オブジェクトと出来上がりです。
ここにトリックがあります:MutableInteger
またはより良いHolder
パターンは、参照によってプリミティブ値を渡すためのソリューションです。
現在idl2java
、IDL に参照パラメータがある場合、CORBA コンパイラで使用されています。
あなたの特定のケースでは、あなたが示した方法があまりにも一般的であるため、デザインの良し悪しについてはお答えできません。考えてみてください。入力として、暗号化のように、マルチメディア情報に何らかの後処理関数を適用する場合は、参照渡しを使用します。私には、以下は良いデザインに見えます
encrypt(x);
VS
x = encrypt(x);