-
Notifications
You must be signed in to change notification settings - Fork 5k
Remove System.Collection.NonGeneric from SqlClient contract #6527
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2,19 +2,14 @@ | |||||||||
// The .NET Foundation licenses this file to you under the MIT license. | ||||||||||
// See the LICENSE file in the project root for more information. | ||||||||||
|
||||||||||
|
||||||||||
|
||||||||||
//------------------------------------------------------------------------------ | ||||||||||
|
||||||||||
|
||||||||||
using System.Data.Common; | ||||||||||
|
||||||||||
using System.Collections; | ||||||||||
using System.Collections.Generic; | ||||||||||
using System.Data.Common; | ||||||||||
using System.Diagnostics; | ||||||||||
|
||||||||||
namespace System.Data.SqlClient | ||||||||||
{ | ||||||||||
public sealed class SqlBulkCopyColumnMappingCollection : CollectionBase | ||||||||||
public sealed class SqlBulkCopyColumnMappingCollection : ICollection, IEnumerable, IList | ||||||||||
{ | ||||||||||
private enum MappingSchema | ||||||||||
{ | ||||||||||
|
@@ -25,33 +20,45 @@ private enum MappingSchema | |||||||||
OrdinalsOrdinals = 4, | ||||||||||
} | ||||||||||
|
||||||||||
private bool _readOnly; | ||||||||||
private readonly List<object> _list = new List<object>(); | ||||||||||
private MappingSchema _mappingSchema = MappingSchema.Undefined; | ||||||||||
|
||||||||||
internal SqlBulkCopyColumnMappingCollection() | ||||||||||
{ | ||||||||||
} | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping this[int index] | ||||||||||
{ | ||||||||||
get | ||||||||||
{ | ||||||||||
return (SqlBulkCopyColumnMapping)this.List[index]; | ||||||||||
} | ||||||||||
} | ||||||||||
public int Count => _list.Count; | ||||||||||
|
||||||||||
internal bool ReadOnly { get; set; } | ||||||||||
|
||||||||||
bool ICollection.IsSynchronized => false; | ||||||||||
|
||||||||||
object ICollection.SyncRoot => NonGenericList.SyncRoot; | ||||||||||
|
||||||||||
bool IList.IsFixedSize => false; | ||||||||||
|
||||||||||
// This always returns false in the full framework, regardless | ||||||||||
// of the value of the internal ReadOnly property. | ||||||||||
bool IList.IsReadOnly => false; | ||||||||||
|
||||||||||
internal bool ReadOnly | ||||||||||
object IList.this[int index] | ||||||||||
{ | ||||||||||
get | ||||||||||
{ | ||||||||||
return _readOnly; | ||||||||||
return NonGenericList[index]; | ||||||||||
} | ||||||||||
set | ||||||||||
{ | ||||||||||
_readOnly = value; | ||||||||||
if (value == null) | ||||||||||
{ | ||||||||||
throw new ArgumentNullException(nameof(value)); | ||||||||||
} | ||||||||||
|
||||||||||
NonGenericList[index] = value; | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping this[int index] => (SqlBulkCopyColumnMapping)_list[index]; | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping Add(SqlBulkCopyColumnMapping bulkCopyColumnMapping) | ||||||||||
{ | ||||||||||
|
@@ -62,35 +69,31 @@ public SqlBulkCopyColumnMapping Add(SqlBulkCopyColumnMapping bulkCopyColumnMappi | |||||||||
{ | ||||||||||
throw SQL.BulkLoadNonMatchingColumnMapping(); | ||||||||||
} | ||||||||||
InnerList.Add(bulkCopyColumnMapping); | ||||||||||
_list.Add(bulkCopyColumnMapping); | ||||||||||
return bulkCopyColumnMapping; | ||||||||||
} | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping Add(string sourceColumn, string destinationColumn) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
SqlBulkCopyColumnMapping column = new SqlBulkCopyColumnMapping(sourceColumn, destinationColumn); | ||||||||||
return Add(column); | ||||||||||
return Add(new SqlBulkCopyColumnMapping(sourceColumn, destinationColumn)); | ||||||||||
} | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping Add(int sourceColumnIndex, string destinationColumn) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
SqlBulkCopyColumnMapping column = new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumn); | ||||||||||
return Add(column); | ||||||||||
return Add(new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumn)); | ||||||||||
} | ||||||||||
|
||||||||||
public SqlBulkCopyColumnMapping Add(string sourceColumn, int destinationColumnIndex) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
SqlBulkCopyColumnMapping column = new SqlBulkCopyColumnMapping(sourceColumn, destinationColumnIndex); | ||||||||||
return Add(column); | ||||||||||
return Add(new SqlBulkCopyColumnMapping(sourceColumn, destinationColumnIndex)); | ||||||||||
} | ||||||||||
public SqlBulkCopyColumnMapping Add(int sourceColumnIndex, int destinationColumnIndex) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
SqlBulkCopyColumnMapping column = new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumnIndex); | ||||||||||
return Add(column); | ||||||||||
return Add(new SqlBulkCopyColumnMapping(sourceColumnIndex, destinationColumnIndex)); | ||||||||||
} | ||||||||||
|
||||||||||
private void AssertWriteAccess() | ||||||||||
|
@@ -101,80 +104,54 @@ private void AssertWriteAccess() | |||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
new public void Clear() | ||||||||||
public void Clear() | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
base.Clear(); | ||||||||||
_list.Clear(); | ||||||||||
} | ||||||||||
|
||||||||||
public bool Contains(SqlBulkCopyColumnMapping value) | ||||||||||
{ | ||||||||||
return (-1 != InnerList.IndexOf(value)); | ||||||||||
} | ||||||||||
public bool Contains(SqlBulkCopyColumnMapping value) => _list.Contains(value); | ||||||||||
|
||||||||||
public void CopyTo(SqlBulkCopyColumnMapping[] array, int index) | ||||||||||
{ | ||||||||||
InnerList.CopyTo(array, index); | ||||||||||
} | ||||||||||
public void CopyTo(SqlBulkCopyColumnMapping[] array, int index) => _list.CopyTo(array, index); | ||||||||||
|
||||||||||
internal void CreateDefaultMapping(int columnCount) | ||||||||||
{ | ||||||||||
for (int i = 0; i < columnCount; i++) | ||||||||||
{ | ||||||||||
InnerList.Add(new SqlBulkCopyColumnMapping(i, i)); | ||||||||||
_list.Add(new SqlBulkCopyColumnMapping(i, i)); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
public int IndexOf(SqlBulkCopyColumnMapping value) | ||||||||||
{ | ||||||||||
return InnerList.IndexOf(value); | ||||||||||
} | ||||||||||
public IEnumerator GetEnumerator() => _list.GetEnumerator(); | ||||||||||
|
||||||||||
public int IndexOf(SqlBulkCopyColumnMapping value) => _list.IndexOf(value); | ||||||||||
|
||||||||||
public void Insert(int index, SqlBulkCopyColumnMapping value) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
InnerList.Insert(index, value); | ||||||||||
_list.Insert(index, value); | ||||||||||
} | ||||||||||
|
||||||||||
public void Remove(SqlBulkCopyColumnMapping value) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
InnerList.Remove(value); | ||||||||||
_list.Remove(value); | ||||||||||
} | ||||||||||
|
||||||||||
new public void RemoveAt(int index) | ||||||||||
public void RemoveAt(int index) | ||||||||||
{ | ||||||||||
AssertWriteAccess(); | ||||||||||
base.RemoveAt(index); | ||||||||||
_list.RemoveAt(index); | ||||||||||
} | ||||||||||
|
||||||||||
internal void ValidateCollection() | ||||||||||
{ | ||||||||||
MappingSchema mappingSchema; | ||||||||||
foreach (SqlBulkCopyColumnMapping a in this) | ||||||||||
foreach (SqlBulkCopyColumnMapping a in _list) | ||||||||||
{ | ||||||||||
if (a.SourceOrdinal != -1) | ||||||||||
{ | ||||||||||
if (a.DestinationOrdinal != -1) | ||||||||||
{ | ||||||||||
mappingSchema = MappingSchema.OrdinalsOrdinals; | ||||||||||
} | ||||||||||
else | ||||||||||
{ | ||||||||||
mappingSchema = MappingSchema.OrdinalsNames; | ||||||||||
} | ||||||||||
} | ||||||||||
else | ||||||||||
{ | ||||||||||
if (a.DestinationOrdinal != -1) | ||||||||||
{ | ||||||||||
mappingSchema = MappingSchema.NemesOrdinals; | ||||||||||
} | ||||||||||
else | ||||||||||
{ | ||||||||||
mappingSchema = MappingSchema.NamesNames; | ||||||||||
} | ||||||||||
} | ||||||||||
mappingSchema = a.SourceOrdinal != -1 ? | ||||||||||
(a.DestinationOrdinal != -1 ? MappingSchema.OrdinalsOrdinals : MappingSchema.OrdinalsNames) : | ||||||||||
(a.DestinationOrdinal != -1 ? MappingSchema.NemesOrdinals : MappingSchema.NamesNames); | ||||||||||
|
||||||||||
if (_mappingSchema == MappingSchema.Undefined) | ||||||||||
{ | ||||||||||
|
@@ -189,6 +166,49 @@ internal void ValidateCollection() | |||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
void ICollection.CopyTo(Array array, int index) => NonGenericList.CopyTo(array, index); | ||||||||||
|
||||||||||
int IList.Add(object value) | ||||||||||
{ | ||||||||||
if (value == null) | ||||||||||
{ | ||||||||||
throw new ArgumentNullException(nameof(value)); | ||||||||||
} | ||||||||||
|
||||||||||
return NonGenericList.Add(value); | ||||||||||
} | ||||||||||
|
||||||||||
bool IList.Contains(object value) => NonGenericList.Contains(value); | ||||||||||
|
||||||||||
int IList.IndexOf(object value) => NonGenericList.IndexOf(value); | ||||||||||
|
||||||||||
void IList.Insert(int index, object value) | ||||||||||
{ | ||||||||||
if (value == null) | ||||||||||
{ | ||||||||||
throw new ArgumentNullException(nameof(value)); | ||||||||||
} | ||||||||||
|
||||||||||
NonGenericList.Insert(index, value); | ||||||||||
} | ||||||||||
|
||||||||||
void IList.Remove(object value) | ||||||||||
{ | ||||||||||
if (value == null) | ||||||||||
{ | ||||||||||
throw new ArgumentNullException(nameof(value)); | ||||||||||
} | ||||||||||
|
||||||||||
bool removed = _list.Remove(value); | ||||||||||
|
||||||||||
// This throws on full framework, so it will also throw here. | ||||||||||
if (!removed) | ||||||||||
{ | ||||||||||
throw new ArgumentException(SR.Arg_RemoveArgNotFound); | ||||||||||
} | ||||||||||
} | ||||||||||
|
||||||||||
private IList NonGenericList => _list; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to call some of the explicitly implemented non-generic collection interface members on void ICollection.CopyTo(Array array, int index) => ((ICollection)_list).CopyTo(array, index); We did the same thing in Lines 247 to 250 in c20fcbe
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK 👍 |
||||||||||
} | ||||||||||
} | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With
CollectionBase
the propertyint Capacity
was available as well. With the implementation of the interfaces, the property cannot be used by the clients.This will break any clients using the property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
Capacity
a commonly used property onSqlBulkCopyColumnMappingCollection
? None of the other collections in CoreFX that implementCollectionBase
in the full framework include it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to think about: if
SqlBulkCopyColumnMappingCollection
were a new API being added to CoreFX today, it'd just derive fromSystem.Collections.ObjectModel.Collection<T>
which does not have a publicCapacity
property.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about the usage statistics. I was talking strictly in terms of backward compatibility and wanted to know your thoughts on
Capacity
property.I know that the APIs have been removed from CoreFX to streamline the surface area and to better programming models.