如何实现ICollection.CopyTo方法
本文关键字:ICollection CopyTo 方法 实现 何实现 | 更新日期: 2023-09-27 18:34:43
我正在编写一个实现ICollection<T>
和ICollection
接口的类。
MSDN表示这些有点不同。 ICollection<T>.CopyTo
接受T[]
论点,而ICollection.CopyTo
接受System.Array
论点。引发的异常之间也存在差异。
这是我对通用方法的实现(我相信它是功能齐全的(:
void ICollection<PlcParameter>.CopyTo(PlcParameter[] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException("array");
if (arrayIndex < 0)
throw new ArgumentOutOfRangeException("arrayIndex");
if (array.Length - arrayIndex < Count)
throw new ArgumentException("Not enough elements after arrayIndex in the destination array.");
for (int i = 0; i < Count; ++i)
array[i + arrayIndex] = this[i];
}
但是,该方法的非通用版本让我有点困惑。首先,如何检查以下异常情况?
源 ICollection 的类型不能自动强制转换为目标阵列的类型。
其次,有没有办法利用现有的泛型实现来减少代码重复?
这是我正在进行的实施:
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
throw new ArgumentNullException("array");
if (index < 0)
throw new ArgumentOutOfRangeException("arrayIndex");
if (array.Rank > 1)
throw new ArgumentException("array is multidimensional.");
if (array.Length - index < Count)
throw new ArgumentException("Not enough elements after index in the destination array.");
for (int i = 0; i < Count; ++i)
array.SetValue(this[i], i + index);
}
您已经完成了实现ICollection<T>.CopyTo
的大部分工作。
ICollection.CopyTo
有四种可能性:
- 它将与
ICollection<T>
相同
。 - 它将失败,原因
ICollection<T>
会失败。 - 它将由于等级不匹配而失败。
- 它将由于类型不匹配而失败。
我们可以通过调用 ICollection<T>.CopyTo
来处理前两个。
在每种情况下,array as PlcParameter[]
都会给我们一个对强类型数组的引用。
在后一种情况下,它不会。
不过,我们确实想单独捕获array == null
:
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
throw new ArgumentNullException("array");
PlcParameter[] ppArray = array as PlcParameter[];
if (ppArray == null)
throw new ArgumentException();
((ICollection<PlcParameter>)this).CopyTo(ppArray, index);
}
如果您真的想要,您可以在ppArray
为 null 的情况下测试 array.Rank == 1
,并相应地更改错误消息。
(顺便说一句,你为什么要显式实现ICollection<PlcParameter>.CopyTo
?明确实现工作可能足够有用,所以人们不必全部投射到它。
在非泛型CopyTo
中,可能会发生以下情况:
- 类型实际匹配:调用泛型版本
- 数组是
object[]
:也处理这个,特别是如果T
是引用类型,因为在这种情况下T[]
可以转换为object[]
- 如果您的集合是字典,则还可以处理
KeyValuePair[]
数组和DictionaryEntry[]
数组。
因此,在一般情况下,您应该使用以下实现:
void ICollection.CopyTo(Array array, int index)
{
if (array != null && array.Rank != 1)
throw new ArgumentException("Only single dimensional arrays are supported for the requested action.", "array");
// 1. call the generic version
T[] typedArray = array as T[];
if (typedArray != null)
{
CopyTo(typedArray, index);
return;
}
// 2. object[]
object[] objectArray = array as object[];
if (objectArray != null)
{
for (int i = 0; i < size; i++)
{
objectArray[index++] = GetElementAt(i);
}
}
throw new ArgumentException("Target array type is not compatible with the type of items in the collection.");
}