C# - よく使うクラス - List - 基本

クラウディア 
1. 概要
2. 例
3. 解説

1. 概要

 「List」というクラスがあります。  次ページの「Dictionary」という型があって、今は、どうもそちらが推奨されているらしいのですが。  わたしは、「List」の方が使い勝手がいいのです。  「【C#】【Unity】Dictionary と List の速度比較」というページで読むと、おおむね「List」の方が「Dictionary」より速いらしい。  まぁ、速度のことは置いておいても、わたしは、「List」の方がなじめるのだな。  なじめるなじめないは、置いていても、少なくとも、「.NET Framework 4.0」では、「Dictionary」型は、「xml」ダンプができないのである。  これは、非常に痛い。  データを目視で確認するのに、「.xml」でダンプするのは、非常に役立つのであります。  2つのデータを比較するにも、バイナリダンプでは、人が比較するには、困難を極めます。  「.xml」であれば、不一致点を見るだけで、何が違うのかがわかりますからな。  「List」型で気になるところは

using System.Collections.Generic;
 と「namespace」を使わねばならんので、「Generic」というキーワードを使用していることです。  「List<T> クラス (System.Collections.Generic) 」を読むと。  「.Net Framework 6」でも、有効(2021年12月2日現在)なようなので、まだ使えそうです。  本ページは、下記のサイトを参考にさせていただきました。
List<T>.RemoveAll(Predicate<T>) メソッド (System.Collections.Generic) | Microsoft Docs」
「[C#] 条件に合致した List の要素を削除する(.RemoveAll)

2. 例

 サンプルソースとして、下記のようなものを書いてみました。

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Collections.Generic;

[Serializable]
public class ObjectCopy
{
	internal object Clone()
	{
		object objCopy = new object();
		MemoryStream ms = new MemoryStream();
		XmlSerializer xml = new XmlSerializer(this.GetType());
		xml.Serialize(ms, this);
		ms.Position = 0;
		objCopy = xml.Deserialize((Stream)ms);
		ms.Close();
		return objCopy;
	}
}

[Serializable]
public class myClass : ObjectCopy
{
	public int 	  age  = 0;
	public string name = String.Empty;

	public myClass DeepCopy()
	{
		return (myClass)this.Clone();
	}
}

public class HelloWorld
{
	static public void Main ()
	{
		List<myClass> list01 = new List<myClass>
			{
				new myClass { age = 20, name = @"hogehoge" },
				new myClass { age = 20, name = @"fugafuga" },
				new myClass { age = 21, name = @"piyopiyo" },
			};

        Console.WriteLine(@"list01.Count = [" + list01.Count + "]");

		foreach (myClass m in list01)
		{
	        Console.WriteLine(@"age = [" + m.age + @"] name[" + m.name + @"]");
		}

        Console.WriteLine();

		List<myClass> list02 = list01.FindAll(x => x.age == 20);

        Console.WriteLine("list02.Count = [" + list02.Count + @"]");

		foreach (myClass m in list02)
		{
	        Console.WriteLine(@"age = [" + m.age + @"] name[" + m.name + @"]");
		}

        Console.WriteLine ();

		myClass m01 = list01.Find(x => x.age == 20 && x.name == @"fugafuga");

		if (m01 != null)
		{
        	Console.WriteLine(@"m01 age = [" + m01.age + @"] name[" + m01.name + @"]");
		}
		else
		{
        	Console.WriteLine(@"m01 is null");
		}

		myClass m02 = list01.Find(x => x.age == 20 && x.name == @"hegehge");

		if (m02 != null)
		{
	        Console.WriteLine(@"m02 age = [" + m02.age + @"] name[" + m02.name + @"]");
		}
		else
		{
        	Console.WriteLine(@"m02 is null");
		}

        Console.WriteLine ();

		List<myClass> list03 = new List<myClass>
			{
				new myClass { age = 22, name = @"madamada" },
				new myClass { age = 23, name = @"motomoto" },
				new myClass { age = 24, name = @"mo-i-yo-" },
			};

		list01.AddRange(list03);

        Console.WriteLine(@"list01.Count = [" + list01.Count + "]");

		foreach (myClass m in list01)
		{
	        Console.WriteLine(@"age = [" + m.age + @"] name[" + m.name + @"]");
		}
	}
}
 「FreeBSD 12.2 RELEASE」上の「Mono」で、コンパイル・リンクして、くっきり実行できます。  これをコンソールで実行すると、下記の結果が得られます。

list01.Count = [3]
age = [20] name[hogehoge]
age = [20] name[fugafuga]
age = [21] name[piyopiyo]

list02.Count = [2]
age = [20] name[hogehoge]
age = [20] name[fugafuga]

m01 age = [20] name[fugafuga]
m02 is null

list01.Count = [6]
age = [20] name[hogehoge]
age = [20] name[fugafuga]
age = [21] name[piyopiyo]
age = [22] name[madamada]
age = [23] name[motomoto]
age = [24] name[mo-i-yo-]

3. 解説

 わたしのメモとして、解説しておきます。

		List<myClass> list01 = new List<myClass>
			{
				new myClass { age = 20, name = @"hogehoge" },
				new myClass { age = 20, name = @"fugafuga" },
				new myClass { age = 21, name = @"piyopiyo" },
			};
 上記は、宣言と初期化ですな。  実は、このソースを書くまで、クラスや「List」をいきなり初期化する方法をよく知らなかったのですが、勉強になりました。  初心者の方の参考になればよいのですが。  「Add」や「Remove」なんかは、簡単なので、いちいちメモしておりませんが・・・。

		List<myClass> list02 = list01.FindAll(x => x.age == 20);
 上記は、「List」からある条件によって「List」を収集する例です。

		myClass m01 = list01.Find(x => x.age == 20 && x.name == @"fugafuga");
 上記は、「List」からある条件によって、1件を抽出する例です。  例では、たまたま1件しかないのですが、条件に合う要素が複数件存在する場合は、インデックスの若いものが抽出されるようです。

		myClass m02 = list01.Find(x => x.age == 20 && x.name == @"hegehge");
 上記は、「List」からある条件によって、要素を抽出しようとして、条件に合うものが、存在しない場合です。  この場合、「null」が返ってきます。

		List<myClass> list03 = new List<myClass>
			{
				new myClass { age = 22, name = @"madamada" },
				new myClass { age = 23, name = @"motomoto" },
				new myClass { age = 24, name = @"mo-i-yo-" },
			};

		list01.AddRange(list03);
 上記は、「List」に「List」を結合する例です。  これは、「List の末尾に List を追加する」を参考にさせていただきました。
earthcar(アースカー)
葬送のフリーレン Prime Video
マイニングベース