Skip to content

Commit

Permalink
Added AsReadOnly() extension to ISet<T> (#106037)
Browse files Browse the repository at this point in the history
* Add AsReadOnly extension for ISet<T>

* Fix type forwarding

---------

Co-authored-by: Stephen Toub <stoub@microsoft.com>
  • Loading branch information
Mrxx99 and stephentoub authored Nov 25, 2024
1 parent 6cacfa7 commit ad1f8db
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ------------------------------------------------------------------------------
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

[assembly: System.Runtime.CompilerServices.TypeForwardedTo(typeof(System.Collections.ObjectModel.ReadOnlySet<>))]
33 changes: 1 addition & 32 deletions src/libraries/System.Collections/ref/System.Collections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,38 +582,6 @@ void System.Collections.IEnumerator.Reset() { }
}
}
}
namespace System.Collections.ObjectModel
{
public partial class ReadOnlySet<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlySet<T>, System.Collections.Generic.ISet<T>, System.Collections.ICollection, System.Collections.IEnumerable
{
public ReadOnlySet(System.Collections.Generic.ISet<T> @set) { }
public int Count { get { throw null; } }
public static System.Collections.ObjectModel.ReadOnlySet<T> Empty { get { throw null; } }
protected System.Collections.Generic.ISet<T> Set { get { throw null; } }
bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
public bool Contains(T item) { throw null; }
public System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsSubsetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsSupersetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool Overlaps(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool SetEquals(System.Collections.Generic.IEnumerable<T> other) { throw null; }
void System.Collections.Generic.ICollection<T>.Add(T item) { }
void System.Collections.Generic.ICollection<T>.Clear() { }
void System.Collections.Generic.ICollection<T>.CopyTo(T[] array, int arrayIndex) { }
bool System.Collections.Generic.ICollection<T>.Remove(T item) { throw null; }
bool System.Collections.Generic.ISet<T>.Add(T item) { throw null; }
void System.Collections.Generic.ISet<T>.ExceptWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.IntersectWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.SymmetricExceptWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.UnionWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
#endif // !BUILDING_CORELIB_REFERENCE
namespace System.Collections.Generic
{
Expand All @@ -627,6 +595,7 @@ public static void InsertRange<T>(this System.Collections.Generic.List<T> list,
public static bool Remove<TKey, TValue>(this System.Collections.Generic.IDictionary<TKey, TValue> dictionary, TKey key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out TValue value) { throw null; }
public static bool TryAdd<TKey, TValue>(this System.Collections.Generic.IDictionary<TKey, TValue> dictionary, TKey key, TValue value) { throw null; }
public static System.Collections.ObjectModel.ReadOnlyCollection<T> AsReadOnly<T>(this IList<T> list) { throw null; }
public static System.Collections.ObjectModel.ReadOnlySet<T> AsReadOnly<T>(this ISet<T> set) { throw null; }
public static System.Collections.ObjectModel.ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(this IDictionary<TKey, TValue> dictionary) where TKey : notnull { throw null; }
}
public abstract partial class Comparer<T> : System.Collections.Generic.IComparer<T>, System.Collections.IComparer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Collections.cs" />
<Compile Include="System.Collections.Forwards.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\System.Runtime\ref\System.Runtime.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<Compile Include="System\Collections\Generic\OrderedDictionary.cs" />
<Compile Include="System\Collections\Generic\PriorityQueue.cs" />
<Compile Include="System\Collections\Generic\PriorityQueueDebugView.cs" />
<Compile Include="System\Collections\Generic\ReadOnlySet.cs" />
<Compile Include="System\Collections\Generic\SortedDictionary.cs" />
<Compile Include="System\Collections\Generic\SortedList.cs" />
<Compile Include="System\Collections\Generic\SortedSet.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ public void AsReadOnly_TurnsIListIntoReadOnlyCollection()
CollectionAsserts.Equal(list, readOnlyCollection);
}

[Fact]
public void AsReadOnly_TurnsISetIntoReadOnlySet()
{
ISet<string> set = new HashSet<string> { "A", "B" };
ReadOnlySet<string> readOnlySet = set.AsReadOnly();
Assert.NotNull(readOnlySet);
Assert.NotSame(set, readOnlySet);
Assert.NotSame(readOnlySet, set.AsReadOnly());
CollectionAsserts.Equal(set, readOnlySet);
}

[Fact]
public void AsReadOnly_TurnsIDictionaryIntoReadOnlyDictionary()
{
Expand All @@ -134,6 +145,13 @@ public void AsReadOnly_NullIList_ThrowsArgumentNullException()
Assert.Throws<ArgumentNullException>("list", () => list.AsReadOnly());
}

[Fact]
public void AsReadOnly_NullISet_ThrowsArgumentNullException()
{
ISet<string> set = null;
AssertExtensions.Throws<ArgumentNullException>("set", () => set.AsReadOnly());
}

[Fact]
public void AsReadOnly_NullIDictionary_ThrowsArgumentNullException()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\ObjectModel\CollectionHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\ObjectModel\ReadOnlyCollection.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\ObjectModel\ReadOnlySet.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\DefaultValueAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\EditorBrowsableAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\EditorBrowsableState.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ public static bool Remove<TKey, TValue>(this IDictionary<TKey, TValue> dictionar
public static ReadOnlyCollection<T> AsReadOnly<T>(this IList<T> list) =>
new ReadOnlyCollection<T>(list);

/// <summary>
/// Returns a read-only <see cref="ReadOnlySet{T}"/> wrapper
/// for the specified set.
/// </summary>
/// <typeparam name="T">The type of elements in the set.</typeparam>
/// <param name="set">The set to wrap.</param>
/// <returns>An object that acts as a read-only wrapper around the current <see cref="ISet{T}"/>.</returns>
/// <exception cref="ArgumentNullException"><paramref name="set"/> is null.</exception>
public static ReadOnlySet<T> AsReadOnly<T>(this ISet<T> set) =>
new ReadOnlySet<T>(set);

/// <summary>
/// Returns a read-only <see cref="ReadOnlyDictionary{TKey, TValue}"/> wrapper
/// for the current dictionary.
Expand Down
29 changes: 29 additions & 0 deletions src/libraries/System.Runtime/ref/System.Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8470,6 +8470,35 @@ void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
public partial class ReadOnlySet<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlySet<T>, System.Collections.Generic.ISet<T>, System.Collections.ICollection, System.Collections.IEnumerable
{
public ReadOnlySet(System.Collections.Generic.ISet<T> @set) { }
public int Count { get { throw null; } }
public static System.Collections.ObjectModel.ReadOnlySet<T> Empty { get { throw null; } }
protected System.Collections.Generic.ISet<T> Set { get { throw null; } }
bool System.Collections.Generic.ICollection<T>.IsReadOnly { get { throw null; } }
bool System.Collections.ICollection.IsSynchronized { get { throw null; } }
object System.Collections.ICollection.SyncRoot { get { throw null; } }
public bool Contains(T item) { throw null; }
public System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
public bool IsProperSubsetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsProperSupersetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsSubsetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool IsSupersetOf(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool Overlaps(System.Collections.Generic.IEnumerable<T> other) { throw null; }
public bool SetEquals(System.Collections.Generic.IEnumerable<T> other) { throw null; }
void System.Collections.Generic.ICollection<T>.Add(T item) { }
void System.Collections.Generic.ICollection<T>.Clear() { }
void System.Collections.Generic.ICollection<T>.CopyTo(T[] array, int arrayIndex) { }
bool System.Collections.Generic.ICollection<T>.Remove(T item) { throw null; }
bool System.Collections.Generic.ISet<T>.Add(T item) { throw null; }
void System.Collections.Generic.ISet<T>.ExceptWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.IntersectWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.SymmetricExceptWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.Generic.ISet<T>.UnionWith(System.Collections.Generic.IEnumerable<T> other) { }
void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
}
}
namespace System.ComponentModel
{
Expand Down

0 comments on commit ad1f8db

Please sign in to comment.