你可以创建一个实现IList接口的类,在这个类里面你会有一个List,它会保存对象,你会通过list几乎所有的方法,除了:Add,包含 Insert 和 SET[Index],您将使用方法ReferenceEquals 来检查两个对象是否具有相同的引用。
如果你有这门课
public class Person
{
protected bool Equals(Person other) => Id == other?.Id;
public override int GetHashCode() => Id;
public static bool operator ==(Person left, Person right) => Equals(left, right);
public static bool operator !=(Person left, Person right) => !Equals(left, right);
public int Id { get; set; }
public override bool Equals(object obj) => Equals(obj as Person);
}
如果你运行这段代码
var person = new Person() { Id = 1 };
var person2 = new Person() { Id = 1 };
Console.WriteLine(person == person2);
你会发现两个人都是平等的。
现在让我们创建一个ListByReference<T>
public class ListByReference<T> : IList<T>
{
private readonly List<T> _list;
public ListByReference()
{
_list = new List<T>();
}
public IEnumerator<T> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void Add(T item)
{
if (ObjectExists(item))
return;
_list.Add(item);
}
public void Clear() => _list.Clear();
public bool Contains(T item) => ObjectExists(item);
public void CopyTo(T[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
public bool Remove(T item) => _list.Remove(item);
public int Count => _list.Count;
public bool IsReadOnly => false;
public int IndexOf(T item) => _list.IndexOf(item);
public void Insert(int index, T item)
{
if (ObjectExists(item))
return;
_list.Insert(index, item);
}
public void RemoveAt(int index) => _list.RemoveAt(index);
public T this[int index]
{
get { return _list[index]; }
set
{
if (ObjectExists(value))
return;
_list[index] = value;
}
}
private bool ObjectExists(T item) => _list.Any(i => ReferenceEquals(i, item));
}
然后我们可以测试我们的类
var person = new Person() { Id = 1 };
var person2 = new Person() { Id = 1 };
var listByReference = new ListByReference<Person>();
listByReference.Add(person);
listByReference.Add(person2);
listByReference.Add(person);
Console.WriteLine(listByReference.Count);
Console.WriteLine(listByReference.Contains(person));
Console.WriteLine(listByReference.Contains(person2));
Console.WriteLine(listByReference.Contains(new Person() { Id = 1 }));
输出是
2
是的
是的
错误
如您所见,我调用了 add 3 次,但名单上只有 2 个人,因为第一个已经添加。
当尝试添加一些已经存在的对象时,我选择不抛出异常,但您可以根据需要进行修改。