トップ回答者
ArrayListのコンストラクタについての問題です。

質問
-
今、「ファイルを開く」ダイアログボックス設定のPGを組み込んでいます。
下記はArrayListについての一部のコードです。コード ブロックArrayList ArrayList1 = new ArrayList();
FilterInfo filterInfo = new FilterInfo();
FilterInfo filterInfo1 = new FilterInfo();
FilterInfo filterInfo2 = new FilterInfo();filterInfo.Name = "XMLファイル(*.xml)";
filterInfo.Extension = ".xml";
filterInfo1.Name = "テキスト文書(*.txt)";
filterInfo1.Extension = ".txt";
filterInfo2.Name = "画像ファイル(*.jpg)";
filterInfo2.Extension = ".jpg";
ArrayList1.Add(filterInfo);
ArrayList1.Add(filterInfo1);
ArrayList1.Add(filterInfo2);*FilterInfo*では、 フィルタインフォ というクラスです。
*Name(get,set)* ファイル種類名
*Extension(get,set)* ファイル拡張子名上記コードは、ArrayListクラスのオーバーライド(コピーコンストラクタ)
を利用すれば、たぶん短くになると思いますが、やりかたはわからないです。どうしたら実現できるのか、
教えて頂けないでしょうか。
よろしくお願い致します。
回答
-
やりたいことは「AddとFilterInfoの作成・設定を一行にしたい」でしょうか?
コード ブロックpublic static class FilterInfoCreator
{
public static FilterInfo Create(string name, string extension)
{
FilterInfo info = new FilterInfo();
info.Name = name;
info.Extension = extension;return info;
}
}class Test
{
public static void TestMain()
{
List<FilterInfo> list = new List<FilterInfo>();
list.Add(FilterInfoCreator.Create("XMLファイル(*.xml)", ".xml"));
list.Add(FilterInfoCreator.Create("テキスト文書(*.txt)", ".txt"));
list.Add(FilterInfoCreator.Create("画像ファイル(*.jpg)", ".jpg"));
}
}ArrayListの方じゃなくて、FilterInfoを一行で作れるようにするとかも1つの方法かと思います。
-
剣道 さんからの引用
arrList内部でFilterInfoのインスタンスを複製して管理することというのは、
"new DialogUtil.FilterInfo()"は
Addメソッドの引数として、FilterInfoのインスタンスを作成することなんでしょうか。ArrayListのAddメソッドの引数に渡すのは、あるインスタンスへの参照です。
例えば、以下のようにするとどうなるでしょうか?FilterInfo filterInfo = new FilterInfo();
filterInfo.Name = "XMLファイル(*.xml)";
filterInfo.Extension = ".xml";
ArrayList1.Add(filterInfo);filterInfo.Name = "テキスト文書(*.txt)";
filterInfo.Extension = ".txt";
ArrayList1.Add(filterInfo);filterInfo.Name = "画像ファイル(*.jpg)";
filterInfo.Extension = ".jpg";
ArrayList1.Add(filterInfo);ArrayList1の中身は全く同じ3つのものになります。ArrayListは実態(インスタンス)がどこにあるかという番地(参照)を保持しているにすぎませんので、3つとも同じ参照を保持していることになり、その参照先には最後にセットされた"画像ファイル(*.jpg)"と".jpg"があります。
上記のコードではnewしているのは最初の1行だけです。例えるならば、ここでマンションの部屋を作って、部屋の番号をfilterInfoにセットしています。
部屋は1つしか作っていないことに注意して下さい。
上記で作成された部屋の番号を203号室としましょう。
ArrayList1には、203号室という情報が3つ入っていることになります。話を変えます。
FilterInfo filterInfo = new FilterInfo();
filterInfo.Name = "XMLファイル(*.xml)";
filterInfo.Extension = ".xml";
ArrayList1.Add(filterInfo);上記コードのArrayList1には203号室という情報のみ入っています。また、ArrayList1は203号室に誰が入るかを管理することができませんので、ArrayList1が知らない間に203号室の住居人(NameとExtension)が変わっている可能性もあります。
剣道さんの記述にコピーコンストラクタという言葉があったので、ArrayList1が知らない間に住居人が変わると困るというように私は想像しました。
つまり、Class ArrayListWrapper
{
ArrayList _arrayList = new ArrayList();public void Add(FilterInfo filterinfo)
{
FilterInfo fi = new FilterInfo(); //新しい部屋を作る。503号室ができたとする。fi.Name = filterinfo.Name;
fi.Extension = filterinfo.Extension;_arrayList.Add(fi);
}
}のようにして新しい部屋を作って、そこに住居人をコピーして住まわせることかと思ったのです。(クローン人間ですね(^^;)
203号室と503号室には全く同じ住居人(NameとExtension)がいることになります。(503号室にいるのはクローン人間です。)
このため、このあと203号室とその住居人がどうなろうが、ArrayListWrapper内にある503号室とその住居人には全く影響がないわけです。
私が、「考えてみれば、Addメソッドの引数でnewされているため、newされたインスタンスをarrList以外で参照していませんから、arrList内部でFilterInfoのインスタンスを複製して管理することと実質は同じようなことになりますね。」
と書いたのは、203号室という情報はarrList以外にはわからないので、他から203号室をいじられる心配がないため、503号室というコピーを作らなくても同じようなことだと思ったからです。つまり、ArrayList内でFilterInfoのインスタンスを作っているのと実質的には変わらないわけです。
すべての返信
-
やりたいことは「AddとFilterInfoの作成・設定を一行にしたい」でしょうか?
コード ブロックpublic static class FilterInfoCreator
{
public static FilterInfo Create(string name, string extension)
{
FilterInfo info = new FilterInfo();
info.Name = name;
info.Extension = extension;return info;
}
}class Test
{
public static void TestMain()
{
List<FilterInfo> list = new List<FilterInfo>();
list.Add(FilterInfoCreator.Create("XMLファイル(*.xml)", ".xml"));
list.Add(FilterInfoCreator.Create("テキスト文書(*.txt)", ".txt"));
list.Add(FilterInfoCreator.Create("画像ファイル(*.jpg)", ".jpg"));
}
}ArrayListの方じゃなくて、FilterInfoを一行で作れるようにするとかも1つの方法かと思います。
-
trapemiyaさん Azuleanさんへ
返事が遅くなって、すみませんでした。
私が勉強不足のため、ArrayListを採用の意味はまた理解していないです。
trapemiyaさんから教えて頂いた知識をメモにして、将来活用していきたいと思っています。Azuleanさんから教えて頂いた方法を参照し、
FilterInfoクラスで、ふたつ引数のコンストラクタを追加して、解決しました。
public class FilterInfo
{
public string _name; // ファイル名
public string[] _extensions; // ファイル拡張子名public FilterInfo(string fileName, string[] fileExtensions)
{
_name = fileName;
_extensions = fileExtensions;
}*************************************
ArrayList arrList = new ArrayList();
string[] Extensions = { "jpg", "jpeg", "jpe", "jfif","bmp","gif" };// 2つの引数を指定したFilterInfoインスタンスを作成して、ArrayListに追加する。
arrList.Add(new DialogUtil.FilterInfo("XMLファイル(*.xml)", "xml"));
arrList.Add(new DialogUtil.FilterInfo("テキスト文書(*.txt)", "txt"));
arrList.Add(new DialogUtil.FilterInfo("画像ファイル(*.JPG;*.JPEG;*.JPE;*.JFIF;*.BMP;*.GIF)", Extensions));迅速にご丁寧に回答していただきまして、心から感謝しています。
非常に勉強になりました。
また、よろしくお願いたします。 -
剣道 さんからの引用
私が勉強不足のため、ArrayListを採用の意味はまた理解していないです。以下が参考になると思います。
ジェネリックとは何か?
http://www.atmarkit.co.jp/fdotnet/csharp20/csharp20_02/csharp20_02_01.html剣道 さんからの引用
Azuleanさんから教えて頂いた方法を参照し、
FilterInfoクラスで、ふたつ引数のコンストラクタを追加して、解決しました。考えてみれば、Addメソッドの引数でnewされているため、newされたインスタンスをarrList以外で参照していませんから、arrList内部でFilterInfoのインスタンスを複製して管理することと実質は同じようなことになりますね。
-
trapemiyaさんへ
たくさんのことを教えて頂き、ありがとうございます。
実は、私の目的が、FilterInfoという適当なクラスつくり、複数のインスタンスをarrList に格納して、
foreach 文で、格納した各要素をアクセスしたかったです。今、作ったFilterInfoのインスタンスは、確か他の参照していないです。
恥ずかしいですが、現時点で、単純なことしか分からないです。
クラス内部ということは、ちょっと難しい話だと思います。arrList内部でFilterInfoのインスタンスを複製して管理することというのは、
"new DialogUtil.FilterInfo()"は
Addメソッドの引数として、FilterInfoのインスタンスを作成することなんでしょうか。申し訳ありませんが、よろしければ、簡単に説明して頂けないでしょうか。
よろしくお願いたします。
-
剣道 さんからの引用
arrList内部でFilterInfoのインスタンスを複製して管理することというのは、
"new DialogUtil.FilterInfo()"は
Addメソッドの引数として、FilterInfoのインスタンスを作成することなんでしょうか。ArrayListのAddメソッドの引数に渡すのは、あるインスタンスへの参照です。
例えば、以下のようにするとどうなるでしょうか?FilterInfo filterInfo = new FilterInfo();
filterInfo.Name = "XMLファイル(*.xml)";
filterInfo.Extension = ".xml";
ArrayList1.Add(filterInfo);filterInfo.Name = "テキスト文書(*.txt)";
filterInfo.Extension = ".txt";
ArrayList1.Add(filterInfo);filterInfo.Name = "画像ファイル(*.jpg)";
filterInfo.Extension = ".jpg";
ArrayList1.Add(filterInfo);ArrayList1の中身は全く同じ3つのものになります。ArrayListは実態(インスタンス)がどこにあるかという番地(参照)を保持しているにすぎませんので、3つとも同じ参照を保持していることになり、その参照先には最後にセットされた"画像ファイル(*.jpg)"と".jpg"があります。
上記のコードではnewしているのは最初の1行だけです。例えるならば、ここでマンションの部屋を作って、部屋の番号をfilterInfoにセットしています。
部屋は1つしか作っていないことに注意して下さい。
上記で作成された部屋の番号を203号室としましょう。
ArrayList1には、203号室という情報が3つ入っていることになります。話を変えます。
FilterInfo filterInfo = new FilterInfo();
filterInfo.Name = "XMLファイル(*.xml)";
filterInfo.Extension = ".xml";
ArrayList1.Add(filterInfo);上記コードのArrayList1には203号室という情報のみ入っています。また、ArrayList1は203号室に誰が入るかを管理することができませんので、ArrayList1が知らない間に203号室の住居人(NameとExtension)が変わっている可能性もあります。
剣道さんの記述にコピーコンストラクタという言葉があったので、ArrayList1が知らない間に住居人が変わると困るというように私は想像しました。
つまり、Class ArrayListWrapper
{
ArrayList _arrayList = new ArrayList();public void Add(FilterInfo filterinfo)
{
FilterInfo fi = new FilterInfo(); //新しい部屋を作る。503号室ができたとする。fi.Name = filterinfo.Name;
fi.Extension = filterinfo.Extension;_arrayList.Add(fi);
}
}のようにして新しい部屋を作って、そこに住居人をコピーして住まわせることかと思ったのです。(クローン人間ですね(^^;)
203号室と503号室には全く同じ住居人(NameとExtension)がいることになります。(503号室にいるのはクローン人間です。)
このため、このあと203号室とその住居人がどうなろうが、ArrayListWrapper内にある503号室とその住居人には全く影響がないわけです。
私が、「考えてみれば、Addメソッドの引数でnewされているため、newされたインスタンスをarrList以外で参照していませんから、arrList内部でFilterInfoのインスタンスを複製して管理することと実質は同じようなことになりますね。」
と書いたのは、203号室という情報はarrList以外にはわからないので、他から203号室をいじられる心配がないため、503号室というコピーを作らなくても同じようなことだと思ったからです。つまり、ArrayList内でFilterInfoのインスタンスを作っているのと実質的には変わらないわけです。