C#で渡された配列を加工して配列で返す関数について注意すること
C#で配列を渡す場合は参照渡しになるということを試してみました。
目次
配列を返す関数
配列を作って、その内容をコンソールに出力するアプリです。
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string[] mat = ArrayTest();
// コンソールに出力する
foreach (var p in mat)
{
Console.WriteLine(p);
}
// コンソールを閉じないようにする
Console.ReadKey();
}
private static string[] ArrayTest()
{
// 配列を作成する
string[] ret = { "ほげ", "ぴよ", "ごま" };
return ret;
}
}
}
実行すると、下図のように配列の中身が一行ずつ表示されます。
配列は参照渡しである
C#では配列は参照渡しをされるので、メソッドに配列を渡してメソッド内でその配列を処理すると、もとの配列のデータが書き換えられます。
下記のプログラムでは、Mainで作成した配列をメソッドに引数として渡します。メソッド内では与えられた配列の要素を変更します。そして、メソッドを実行してから元の配列を表示すると、配列のデータが書き換えられていることがわかります。
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string[] mat = { "ほげ", "ぴよ", "ごま" };
ArrayTest(mat);
// コンソールに出力する
foreach (var p in mat)
{
Console.WriteLine(p);
}
// コンソールを閉じないようにする
Console.ReadKey();
}
private static void ArrayTest(string[] ret)
{
ret[0] = "hoge";
}
}
}
実行結果はこうなります。関数「ArrayTest」は何も返さない関数ですが、関数内で配列の要素を変更しています。そうしたら元の配列の「ほげ」が「hoge」に書き換えられてますね。
関数(メソッド)で配列を加工して戻したい
元々の配列をメソッドに渡して、メソッド内で加工して戻り値として配列を戻したいという場合があります。
配列を=で複製すると参照が複製される
メソッド内で=を使って配列を別の変数に代入すると、うまくいきません。これは、=では配列の参照が渡されて、実態のデータはコピーされないからです。
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string[] mat = { "ほげ", "ぴよ", "ごま" };
Console.WriteLine("元の配列");
foreach (var p in mat)
{
Console.WriteLine(p);
}
string[] ret = ArrayTest(mat);
Console.WriteLine("メソッド実行後の元の配列");
foreach (var p in mat)
{
Console.WriteLine(p);
}
Console.WriteLine("メソッドの戻り値の配列");
foreach (var p in ret)
{
Console.WriteLine(p);
}
Console.ReadKey();
}
static string[] ArrayTest(string[] arr)
{
string[] ret = arr;
ret[0] = "hoge";
return ret;
}
}
}
実行結果は下図のようになります。メソッド実行後に元の配列のデータが書き換わってしまっていますね。=を使って配列をコピーしようとしても、元の配列への参照が渡されるだけなのですね。
cloneメソッドで配列を複製する
呼び出し先にメソッド内で配列をcloneします。
using System;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string[] mat = { "ほげ", "ぴよ", "ごま" };
Console.WriteLine("元の配列");
foreach (var p in mat)
{
Console.WriteLine(p);
}
string[] ret = ArrayTest(mat);
Console.WriteLine("メソッド実行後の元の配列");
foreach (var p in mat)
{
Console.WriteLine(p);
}
Console.WriteLine("メソッドの戻り値の配列");
foreach (var p in ret)
{
Console.WriteLine(p);
}
Console.ReadKey();
}
static string[] ArrayTest(string[] arr)
{
var ret = (string[])arr.Clone();
ret[0] = "hoge";
return ret;
}
}
}
実行結果はこうなります。
元の配列の要素を書き換えること無く、メソッド内で配列を処理して戻すことができました。
公開日
広告
C#でデータ処理カテゴリの投稿
- C#でDataAdapterを使ってAccessのデータベースを読み書きしてみた
- C#でDataAdapterを使ってAccessのデータベースを読み書きしてみた(OleDb編)
- C#でDataGridに表示するデータを操作してみた
- C#でDataTableのカラムのデータ型を読んでみた
- C#でDataTableの自動インクリメントをしてみた
- C#でJSON形式のデータを出力してみた
- C#でLinq to objectの結果をDataTableにしてみた
- C#でSQLite3のデータベースを使ってみる(ADO.NET ファクトリーデザインパターン)
- C#でSQLiteを使ってみる(インストール)
- C#でコレクションの要素の数を調べる
- C#でコレクションを内部結合してみた
- C#でコレクションを左外部結合してみた
- C#でコレクションを昇順または降順に並び替える
- C#で渡された配列を加工して配列で返す関数について注意すること
- C#のキューを試してみた
- C#のスタックを試してみた