Step1. Create a generic class named MyCollection<T> which implements ICollection<T> interface. This interface has following members:
- int Count { get; }
- bool IsReadOnly { get; }
- void Add(T item);
- void Clear();
- bool Contains(T item);
- void CopyTo(T[] array, int arrayIndex);
- bool Remove(T item);
To implement these properties and methods, first we create a generic type array _items that is initialized inside constructor of MyCollection<T>. The implementing methods and properties work on this array e.g.
- to add a new item to the array,
- remove an item from the array,
- clear all items from the array,
- check if an item exists in the array,
- count the total number of items in the array etc.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
class MyCollection<T> : ICollection<T>
{
private T[] _items;
public MyCollection(T[] items)
{
// Avoid null references if items is passed as null
_items = items ?? new T[0];
}
public int Count => _items.Length;
public bool IsReadOnly => false;
public void Add(T item)
{
T[] newItems = new T[_items.Length + 1];
for (int i = 0; i < _items.Length; i++)
{
newItems[i] = _items[i];
}
// FIX: The last index is Length, not Length + 1
newItems[_items.Length] = item;
_items = newItems;
}
public void Clear()
{
_items = new T[0];
}
public bool Contains(T item)
{
// FIX: FirstOrDefault with a predicate or EqualityComparer is required for generics.
// It's cleaner to use Array.IndexOf or LINQ's Contains.
return _items.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException(nameof(array));
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException(nameof(arrayIndex), "Index cannot be negative.");
if (array.Length - arrayIndex < _items.Length)
throw new ArgumentException("The destination array is not large enough.");
Array.Copy(_items, 0, array, arrayIndex, _items.Length);
}
public bool Remove(T item)
{
// FIX: Locate the item's index safely across any generic type
int index = Array.IndexOf(_items, item);
if (index < 0) return false; // Item not found
T[] newItems = new T[_items.Length - 1];
// Copy elements before the removed item
Array.Copy(_items, 0, newItems, 0, index);
// Copy elements after the removed item
Array.Copy(_items, index + 1, newItems, index, _items.Length - index - 1);
_items = newItems;
return true;
}
public IEnumerator<T> GetEnumerator()
{
return new MyEnumerator<T>(_items);
}
// FIX: Standard boilerplate implementation for IEnumerable
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}Step2. Create MyEnumerator<T> class which implements IEnumerator<T>. This code uses the logic already explained in the post: Example of a class that Implements generic IEnumerable<T> interfaceclass MyEnumerator<T> : IEnumerator<T>
{
private T[] _items;
private int _index = -1;
public MyEnumerator(T[] items)
{
_items = items;
}
public T Current
{
get
{
if (_index < 0 || _index >= _items.Length)
{
throw new InvalidOperationException("Enumeration has either not started or has already finished.");
}
return _items[_index];
}
}
// FIX: Explicitly implement the legacy non-generic Current property
object IEnumerator.Current => this.Current;
public bool MoveNext()
{
_index++;
return _index < _items.Length;
}
public void Reset()
{
_index = -1;
}
// FIX: Must implement Dispose even if empty for IEnumerator<T>
public void Dispose()
{
// No unmanaged resources to clean up, leave empty.
}
}Step3. Create Program class as consumer of MyCollection<T>class Program
{
static void Main(string[] args)
{
string[] colors = { "red", "green", "blue", "pink" };
MyCollection<string> mycollection = new MyCollection<string>(colors);
Console.WriteLine("Use properties and methods of MyCollection<string>");
Console.WriteLine($"Total items is colors: {mycollection.Count}");
Console.WriteLine($"Does yellow color exists in colors: {mycollection.Contains("yellow")}");
// Add yellow color
mycollection.Add("yellow");
Console.WriteLine($"Does yellow color exists in colors: {mycollection.Contains("yellow")}");
// Remove blue color
var result = mycollection.Remove("blue") ? "Blue color removed" : "Blue color not found";
Console.WriteLine(result);
}
}
OUTPUTUse properties and methods of MyCollection<string>
Total items is colors: 4
Does yellow color exists in colors: True
Does yellow color exists in colors: True
Blue color removed
No comments:
Post a Comment