Home > C# > C# 学び直し > List<T>クラス

List<T>.Containsメソッドの使用例

新規作成日 2017-03-27
最終更新日

msdnで紹介されているList<T>.Containsメソッドの使用例です。List<T>クラスを活用するには、List<T>で使うクラスにインターフェイスを実装する必要があります。

List<T>.Contains メソッド (T)の使用例

List<T>.Contains メソッド (T)

使用例

次の例は、Equalsを実装する単純なビジネス・オブジェクトが含まれているList<T>のContainsとExistsメソッドを説明します。

using System;
using System.Collections.Generic;
// Simple business object. A PartId is used to identify a part 
// but the part name can change. 
// 簡単なビジネス・オブジェクト。
// PartIdは、部品を識別するために使用されますが、部品の名前は、変更することができます。
public class Part : IEquatable<Part>
{
    public string PartName { get; set; }
    public int PartId { get; set; }

    public override string ToString()
    {
        return "ID: " + PartId + "   Name: " + PartName;
    }
    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        Part objAsPart = obj as Part;
        if (objAsPart == null) return false;
        else return Equals(objAsPart);
    }
    public override int GetHashCode()
    {
        return PartId;
    }
    public bool Equals(Part other)
    {
        if (other == null) return false;
        return (this.PartId.Equals(other.PartId));
    }
    // Should also override == and != operators.
    // また、==と!=演算子をオーバーライドする必要があります。
}
public class Example
{
    public static void Main()
    {
        // Create a list of parts.
        // 部品のリストを作成します。
        List<Part> parts = new List<Part>();

        // Add parts to the list.
        // リスト内の部品を書き出します。
        parts.Add(new Part() { PartName = "crank arm", PartId = 1234 });
        parts.Add(new Part() { PartName = "chain ring", PartId = 1334 });
        parts.Add(new Part() { PartName = "regular seat", PartId = 1434 });
        parts.Add(new Part() { PartName = "banana seat", PartId = 1444 });
        parts.Add(new Part() { PartName = "cassette", PartId = 1534 });
        parts.Add(new Part() { PartName = "shift lever", PartId = 1634 }); ;

        // Write out the parts in the list. This will call the overridden ToString method
        // in the Part class.
        // これは、PartクラスでオーバーライドされたToStringメソッドを呼び出します。

        Console.WriteLine();
        foreach (Part aPart in parts)
        {
            Console.WriteLine(aPart);
        }


        // Check the list for part #1734. This calls the IEquatable.Equals method
        // of the Part class, which checks the PartId for equality.
        // 部品#1734のためのリストを確認します。
        // これは、同等かどうかPartIdを確認する、PartクラスのIEquatable.Equalsメソッドを呼び出します。
        Console.WriteLine("\nContains: Part with Id=1734: {0}",
            parts.Contains(new Part { PartId = 1734, PartName = "" }));

        // Find items where name contains "seat".
        // 名前に、"seat"が含まれる項目を検索します。
        Console.WriteLine("\nFind: Part where name contains \"seat\": {0}", 
            parts.Find(x => x.PartName.Contains("seat")));

        // Check if an item with Id 1444 exists.
        // ID 1444の項目が存在するかどうか確認します。
        Console.WriteLine("\nExists: Part with Id=1444: {0}", 
            parts.Exists(x => x.PartId == 1444));

        Console.ReadKey();

        /*This code example produces the following output:
      このコードの例は、次に示す出力を作成します
        ID: 1234   Name: crank arm
        ID: 1334   Name: chain ring
        ID: 1434   Name: regular seat
        ID: 1444   Name: banana seat
        ID: 1534   Name: cassette
        ID: 1634   Name: shift lever

        Contains: Part with Id=1734: False

        Find: Part where name contains "seat": ID: 1434   Name: regular seat

        Exists: Part with Id=1444: True 
         */
    } 
}

次の例には、型Cubeの複雑なオブジェクトのリストが含まれています。

Cubeクラスは、IEquatable.Equalsメソッドを実装しています。 そのため、2つの立方体は、寸法が、同じ場合、等しいと考えられます。この例では、指定された寸法を持っている立方体は、既に、コレクションの中にあるため、Containsメソッドは、trueを返します。

using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        List<Cube> cubes = new List<Cube>();

        cubes.Add(new Cube(8, 8, 4));
        cubes.Add(new Cube(8, 4, 8));
        cubes.Add(new Cube(8, 6, 4));

        if (cubes.Contains(new Cube(8, 6, 4))) {
            Console.WriteLine("同じ立方体は、既に、コレクションの中にあります。");
	// An equal cube is already in the collection.
        }
        else {
            Console.WriteLine("立方体は、追加することができます。");
        }

        //「同じ立方体は、既に、コレクションの中にあります。」と出力します。
	
        Console.ReadKey();
    }
}

public class Cube : IEquatable<Cube>
{

    public Cube(int h, int l, int w)
    {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }
    public int Height { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }

    public bool Equals(Cube other)
    {
        if (this.Height == other.Height && this.Length == other.Length
            && this.Width == other.Width) {
            return true;
        }
        else {
            return false;
        }
    }

}

ICollection<T> インターフェイスの使用例

ICollection<T> インターフェイス

意見

Remarks

ICollection<T>インターフェイスは、System.Collections.Generic名前空間のクラスのための基準となるインターフェイスです。

ICollection<T>インターフェイスは、IEnumerable<T>を拡張します;

IDictionary<TKey, TValue>とIList<T>は、ICollection<T>を拡張する更に特殊化したインターフェイスです。

IDictionary <TKey、TValue>の実装は、Dictionary <TKey、TValue>クラスのようなキーと値の組み合わせのコレクションです。

IList<T>の実装は、値のコレクションです。そして、そのメンバーは、List<T>クラスのような、インデックスによってアクセスできます。

IDictionary<TKey, TValue>インターフェイスもIList<T>インターフェイスも、必要とされるコレクションの必要条件を満していない場合、更に柔軟にするために、その代わりにICollection<T>インターフェイスから、新しいコレクション・クラスを派生します。

Examples

次の例は、BoxCollectionという名前のカスタムBoxオブジェクトのコレクションを作成するために、ICollection<T>インターフェイスを実装しています。各Boxには、height、lengthとwidthプロパティがあり、これは等価を定義するために使用されます。等価は、すべての寸法が同じ、あるいは、体積が同じものを定義できます。Boxクラスは、寸法が同じものとして、既定の同等を定義するために、IEquatable<T>インターフェイスを実装しています。

BoxCollectionクラスは、既定で、コレクション内のBoxが等価かどうか決定するために使用するために、Containsメソッドを実装しています。このメソッドは、Addメソッドによって使用されます。そのため、コレクションに追加されるそれぞれBoxは、固有の設定の寸法を持っています。BoxCollectionクラスは、例の中のBoxSameDimensionsとBoxSameVolクラスのような、指定されたEqualityComparer<T>オブジェクトを取得するContainsメソッドのオーバーロードも提供しています。

この例では、BoxCollectionクラスのIEnumerator <T>インターフェイスも実装しています。そのため、コレクションを列挙できます。

using System;
using System.Collections;
using System.Collections.Generic;

class Program
{
    // BoxCollection.cs
    static void Main(string[] args)
    {

        BoxCollection bxList = new BoxCollection();

        bxList.Add(new Box(10, 4, 6));
        bxList.Add(new Box(4, 6, 10));
        bxList.Add(new Box(6, 10, 4));
        bxList.Add(new Box(12, 8, 10));

        // Same dimensions. Cannot be added:
        // 同じ寸法。追加することはできません:
        bxList.Add(new Box(10, 4, 6));

        // Test the Remove method.
        // Removeメソッドを検証します。
        Display(bxList);
        Console.WriteLine("Removing 6x10x4");
        bxList.Remove(new Box(6, 10, 4));
        Display(bxList);

        // Test the Contains method.
        // Containsメソッドを検証します。
        Box BoxCheck = new Box(8, 12, 10);
        Console.WriteLine("Contains {0}x{1}x{2} by dimensions: {3}",
            BoxCheck.Height.ToString(), BoxCheck.Length.ToString(),
            BoxCheck.Width.ToString(), bxList.Contains(BoxCheck).ToString());

        // Test the Contains method overload with a specified equality comparer.
        // 指定された同等比較演算子でオーバーロードされたContainsメソッドを検証します。
        Console.WriteLine("Contains {0}x{1}x{2} by volume: {3}",
            BoxCheck.Height.ToString(), BoxCheck.Length.ToString(),
            BoxCheck.Width.ToString(), bxList.Contains(BoxCheck,
            new BoxSameVol()).ToString());

        // コンソールが自動で閉じないための処理
        Console.WriteLine("\n");
        Console.WriteLine("何かキーを押すと終了します。");
        Console.ReadKey();
    }
    public static void Display(BoxCollection bxList)
    {
        Console.WriteLine("\nHeight\tLength\tWidth\tHash Code");
        foreach (Box bx in bxList)
        {
            Console.WriteLine("{0}\t{1}\t{2}\t{3}",
                bx.Height.ToString(), bx.Length.ToString(),
                bx.Width.ToString(), bx.GetHashCode().ToString());
        }

        // Results by manipulating the enumerator directly:
        // 列挙子を直接操作した結果:

        //IEnumerator enumerator = bxList.GetEnumerator();
        //Console.WriteLine("\nHeight\tLength\tWidth\tHash Code");
        //while (enumerator.MoveNext())
        //{
        //    Box b = (Box)enumerator.Current;
        //    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
        //    b.Height.ToString(), b.Length.ToString(), 
        //    b.Width.ToString(), b.GetHashCode().ToString());
        //}

        Console.WriteLine();
    }
}

public class Box : IEquatable<Box>
{

    public Box(int h, int l, int w)
    {
        this.Height = h;
        this.Length = l;
        this.Width = w;
    }
    public int Height { get; set; }
    public int Length { get; set; }
    public int Width { get; set; }

    // Defines equality using the
    // BoxSameDimensions equality comparer.
    // BoxSameDimensions同等比較演算子を使用して同等を定義します。
    public bool Equals(Box other)
    {
        if (new BoxSameDimensions().Equals(this, other))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

public class BoxCollection : ICollection<Box>
{
    // The generic enumerator obtained from IEnumerator<Box>
    // by GetEnumerator can also be used with the non-generic IEnumerator.
    // To avoid a naming conflict, the non-generic IEnumerable method
    // is explicitly implemented.
    // また、GetEnumeratorによってIEnumerator<Box>から得られるジェネリックの
    //  enumeratorは、非ジェネリックのIEnumeratorで使用することができます。
    // 名前の衝突を避けるために、非ジェネリックのIEnumerable メソッドは、明示的に実装されます。

    public IEnumerator<Box> GetEnumerator()
    {
        return new BoxEnumerator(this);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return new BoxEnumerator(this);
    }

    // The inner collection to store objects.
    // オブジェクトを格納する内部のコレクション。
    private List<Box> innerCol;

    public BoxCollection()
    {
        innerCol = new List<Box>();
    }

    // Adds an index to the collection.
    // コレクションにインデックスを追加します。
    public Box this[int index]
    {
        get { return (Box)innerCol[index]; }
        set { innerCol[index] = value; }
    }

    // Determines if an item is in the collection
    // by using the BoxSameDimensions equality comparer.
    // BoxSameDimensions同等比較演算子を使用してコレクションの中に項目が存在するか判断します。
    public bool Contains(Box item)
    {
        bool found = false;

        foreach (Box bx in innerCol)
        {
            // Equality defined by the Box
            // class's implmentation of IEquitable<T>.
            // Equalityは、IEquitable<T>のボックス・クラスの実装で定義されます。
            if (bx.Equals(item))
            {
                found = true;
            }
        }

        return found;
    }

    // Determines if an item is in the 
    // collection by using a specified equality comparer.
    // 指定された同等比較演算子を使用してコレクションの中に項目が存在するか判断します。
    public bool Contains(Box item, EqualityComparer<Box> comp)
    {
        bool found = false;

        foreach (Box bx in innerCol)
        {
            if (comp.Equals(bx, item))
            {
                found = true;
            }
        }

        return found;
    }

    // Adds an item if it is not already in the collection
    // as determined by calling the Contains method.
    // もし、コレクションに含まれていない場合、Containsメソッドを呼び出して項目を追加します。
    public void Add(Box item)
    {

        if (!Contains(item))
        {
            innerCol.Add(item);
        }
        else
        {
            // A box with {0}x{1}x{2} dimensions was already added to the collection.
            Console.WriteLine("{0}x{1}x{2}の大きさのボックスは、コレクションにすでに追加されています。",
                item.Height.ToString(), item.Length.ToString(), item.Width.ToString());
        }
    }

    public void Clear()
    {
        innerCol.Clear();
    }

    public void CopyTo(Box[] array, int arrayIndex)
    {
        if (array == null)
            // The array cannot be null.
            throw new ArgumentNullException("配列は、nullではありません。");
        if (arrayIndex < 0)
            // The starting array index cannot be negative.
            throw new ArgumentOutOfRangeException("開始時の配列のインデックスは、マイナスです。");
            if (Count > array.Length - arrayIndex + 1)
            // The destination array has fewer elements than the collection.
            throw new ArgumentException("目的の配列は、コレクションに比べて、より少ない要素を持っています。");

        for (int i = 0; i < innerCol.Count; i++)
        {
            array[i + arrayIndex] = innerCol[i];
        }
    }

    public int Count
    {
        get
        {
            return innerCol.Count;
        }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(Box item)
    {
        bool result = false;

        // Iterate the inner collection to 
        // find the box to be removed.
        // 削除するボックスを見つけるために、内部のコレクションを繰り返します。
        for (int i = 0; i < innerCol.Count; i++)
        {

            Box curBox = (Box)innerCol[i];

            if (new BoxSameDimensions().Equals(curBox, item))
            {
                innerCol.RemoveAt(i);
                result = true;
                break;
            }
        }
        return result;
    }
}


// Defines the enumerator for the Boxes collection.
// (Some prefer this class nested in the collection class.)
// ボックス・コレクションのための列挙子を定義します。
//(いくつかは、コレクション・クラスで入れ子になったこのクラスを好みます。)
public class BoxEnumerator : IEnumerator<Box>
{
    private BoxCollection _collection;
    private int curIndex;
    private Box curBox;


    public BoxEnumerator(BoxCollection collection)
    {
        _collection = collection;
        curIndex = -1;
        curBox = default(Box);

    }

    public bool MoveNext()
    {
        //Avoids going beyond the end of the collection.
        // コレクションの末端を越えることを避ける。
        if (++curIndex >= _collection.Count)
        {
            return false;
        }
        else
        {
            // Set current box to next item in collection.
            // コレクションの次の項目への現在の直方体を設定します。
            curBox = _collection[curIndex];
        }
        return true;
    }

    public void Reset() { curIndex = -1; }

    void IDisposable.Dispose() { }

    public Box Current
    {
        get { return curBox; }
    }


    object IEnumerator.Current
    {
        get { return Current; }
    }

}

// Defines two boxes as equal if they have the same dimensions.
// 同じ面積の時、2つのボックスを等しいと定義します。
public class BoxSameDimensions : EqualityComparer<Box>
{

    public override bool Equals(Box b1, Box b2)
    {
        if (b1.Height == b2.Height && b1.Length == b2.Length
                            && b1.Width == b2.Width)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public override int GetHashCode(Box bx)
    {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        return hCode.GetHashCode();
    }

}

// Defines two boxes as equal if they have the same volume.
// 同じ体積の時、2つのボックスを等しいと定義します。
public class BoxSameVol : EqualityComparer<Box>
{

    public override bool Equals(Box b1, Box b2)
    {
        if ((b1.Height * b1.Length * b1.Width) ==
                (b2.Height * b2.Length * b2.Width))
        {
            return true;
        }
        else
        {
            return false;
        }
    }


    public override int GetHashCode(Box bx)
    {
        int hCode = bx.Height ^ bx.Length ^ bx.Width;
        Console.WriteLine("HC: {0}", hCode.GetHashCode());
        return hCode.GetHashCode();
    }
}


/* 
This code example displays the following output:
このコードの例は、次の出力を表示します:
================================================

A box with 10x4x6 dimensions was already added to the collection.
10x4x6の大きさのボックスは、コレクションにすでに追加されています。

Height  Length  Width   Hash Code
10      4       6       46104728
4       6       10      12289376
6       10      4       43495525
12      8       10      55915408

Removing 6x10x4

Height  Length  Width   Hash Code
10      4       6       46104728
4       6       10      12289376
12      8       10      55915408

Contains 8x12x10 by dimensions: False
Contains 8x12x10 by volume: True 
 */Hello World (in BeanShell)
このエントリーをはてなブックマークに追加

Home PC C# Illustration

Copyright (C) 2011 Horio Kazuhiko(kukekko) All Rights Reserved.
kukekko@gmail.com
ご連絡の際は、お問い合わせページのURLの明記をお願いします。
「掲載内容は私自身の見解であり、所属する組織を代表するものではありません。」