[Foundation] Make the generic collection classes' generic GetEnumerator methods public. (#20808)
When finding an enumerator for the given code: ```cs var collection = new NSSet<NSNumber> (); foreach (var item in collection) { // ... } ``` the C# compiler will first look for any `GetEnumerator` methods. The non-generic `NSSet` class defines a `IEnumerator<NSObject> GetEnumerator<NSObject> ()` method, which, since the generic `NSSet<T>` class doesn't define such a method, is selected. The end result is that the type of the foreach element is `NSObject` (`GetEnumerator`'s return type') - which is somewhat unexpected: ```cs var collection = new NSSet<NSNumber> (); foreach (var item in collection) { Console.WriteLine (item.LongValue); // error CS1061: 'NSObject' does not contain a definition for 'LongValue' } ``` The fix is to define a `IEnumerator<T> GetEnumerator<T> ()` method in the generic `NSSet<T>` class, which the C# will find and choose over the base class' method. Then the type of the foreach element is the correct type, and the following code works: ```cs var collection = new NSSet<NSNumber> (); foreach (var item in collection) { Console.WriteLine (item.LongValue); // it works! } ``` Do this for all our generic collection classes. Also document these methods + all the other public `GetEnumerator` methods.
This commit is contained in:
Родитель
95df610900
Коммит
323d28c220
|
@ -476,7 +476,9 @@ namespace Foundation {
|
|||
return ToArray<NSObject> ();
|
||||
}
|
||||
|
||||
IEnumerator<NSObject> IEnumerable<NSObject>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the array.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the array.</returns>
|
||||
public IEnumerator<NSObject> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<NSObject> (this);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,9 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<TKey>
|
||||
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the array.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the array.</returns>
|
||||
public new IEnumerator<TKey> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TKey> (this);
|
||||
}
|
||||
|
|
|
@ -395,6 +395,8 @@ namespace Foundation {
|
|||
return GetEnumerator ();
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the dictionary.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the dictionary.</returns>
|
||||
public IEnumerator<KeyValuePair<NSObject, NSObject>> GetEnumerator ()
|
||||
{
|
||||
foreach (var key in Keys) {
|
||||
|
|
|
@ -47,6 +47,8 @@ namespace Foundation {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public IEnumerator<nuint> GetEnumerator ()
|
||||
{
|
||||
if (this.Count == 0)
|
||||
|
|
|
@ -185,6 +185,8 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<T> implementation
|
||||
/// <summary>Returns an enumerator that iterates through the array.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the array.</returns>
|
||||
public IEnumerator<TValue> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TValue> (this);
|
||||
|
|
|
@ -311,6 +311,8 @@ namespace Foundation {
|
|||
#endregion
|
||||
|
||||
#region IEnumerable<K,V>
|
||||
/// <summary>Returns an enumerator that iterates through the dictionary.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the dictionary.</returns>
|
||||
public IEnumerator<KeyValuePair<NSObject, NSObject>> GetEnumerator ()
|
||||
{
|
||||
foreach (var key in Keys) {
|
||||
|
|
|
@ -157,7 +157,9 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<TKey>
|
||||
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public new IEnumerator<TKey> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TKey> (this);
|
||||
}
|
||||
|
|
|
@ -162,7 +162,9 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<T> implementation
|
||||
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public new IEnumerator<TKey> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TKey> (this);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ namespace Foundation {
|
|||
return (NSOrderedSet) Runtime.GetNSObject (ObjCRuntime.Messaging.IntPtr_objc_msgSend_IntPtr (class_ptr, Selector.GetHandle (selSetWithArray), a.Handle));
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public IEnumerator<NSObject> GetEnumerator ()
|
||||
{
|
||||
var enumerator = _GetEnumerator ();
|
||||
|
|
|
@ -109,7 +109,9 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<TKey>
|
||||
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public new IEnumerator<TKey> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TKey> (this);
|
||||
}
|
||||
|
|
|
@ -66,6 +66,8 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<T>
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public IEnumerator<NSObject> GetEnumerator ()
|
||||
{
|
||||
var enumerator = _GetEnumerator ();
|
||||
|
|
|
@ -127,7 +127,9 @@ namespace Foundation {
|
|||
}
|
||||
|
||||
#region IEnumerable<TKey>
|
||||
IEnumerator<TKey> IEnumerable<TKey>.GetEnumerator ()
|
||||
/// <summary>Returns an enumerator that iterates through the set.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the set.</returns>
|
||||
public new IEnumerator<TKey> GetEnumerator ()
|
||||
{
|
||||
return new NSFastEnumerator<TKey> (this);
|
||||
}
|
||||
|
|
|
@ -33206,7 +33206,6 @@ M:Foundation.NSDictionary.FromObjectsAndKeys(Foundation.NSObject[],Foundation.NS
|
|||
M:Foundation.NSDictionary.FromObjectsAndKeys(Foundation.NSObject[],Foundation.NSObject[])
|
||||
M:Foundation.NSDictionary.FromObjectsAndKeys(System.Object[],System.Object[],System.IntPtr)
|
||||
M:Foundation.NSDictionary.FromObjectsAndKeys(System.Object[],System.Object[])
|
||||
M:Foundation.NSDictionary.GetEnumerator
|
||||
M:Foundation.NSDictionary.LowlevelObjectForKey(System.IntPtr)
|
||||
M:Foundation.NSDictionary.ToFileAttributes
|
||||
M:Foundation.NSDictionary.TryGetValue(Foundation.NSObject,Foundation.NSObject@)
|
||||
|
@ -33389,7 +33388,6 @@ M:Foundation.NSIndexSet.EncodeTo(Foundation.NSCoder)
|
|||
M:Foundation.NSIndexSet.FromArray(System.Int32[])
|
||||
M:Foundation.NSIndexSet.FromArray(System.UInt32[])
|
||||
M:Foundation.NSIndexSet.FromArray(System.UIntPtr[])
|
||||
M:Foundation.NSIndexSet.GetEnumerator
|
||||
M:Foundation.NSIndexSet.ToArray
|
||||
M:Foundation.NSInflectionRule.EncodeTo(Foundation.NSCoder)
|
||||
M:Foundation.NSInputStream.Dispose(System.Boolean)
|
||||
|
@ -33506,7 +33504,6 @@ M:Foundation.NSMutableArray`1.#ctor(System.UIntPtr)
|
|||
M:Foundation.NSMutableArray`1.Add(`0)
|
||||
M:Foundation.NSMutableArray`1.AddObjects(`0[])
|
||||
M:Foundation.NSMutableArray`1.Contains(`0)
|
||||
M:Foundation.NSMutableArray`1.GetEnumerator
|
||||
M:Foundation.NSMutableArray`1.IndexOf(`0)
|
||||
M:Foundation.NSMutableArray`1.Insert(`0,System.IntPtr)
|
||||
M:Foundation.NSMutableArray`1.InsertObjects(`0[],Foundation.NSIndexSet)
|
||||
|
@ -33545,7 +33542,6 @@ M:Foundation.NSMutableDictionary.FromObjectsAndKeys(Foundation.NSObject[],Founda
|
|||
M:Foundation.NSMutableDictionary.FromObjectsAndKeys(Foundation.NSObject[],Foundation.NSObject[])
|
||||
M:Foundation.NSMutableDictionary.FromObjectsAndKeys(System.Object[],System.Object[],System.IntPtr)
|
||||
M:Foundation.NSMutableDictionary.FromObjectsAndKeys(System.Object[],System.Object[])
|
||||
M:Foundation.NSMutableDictionary.GetEnumerator
|
||||
M:Foundation.NSMutableDictionary.LowlevelFromObjectAndKey(System.IntPtr,System.IntPtr)
|
||||
M:Foundation.NSMutableDictionary.LowlevelSetObject(Foundation.NSObject,System.IntPtr)
|
||||
M:Foundation.NSMutableDictionary.LowlevelSetObject(System.IntPtr,System.IntPtr)
|
||||
|
@ -33810,7 +33806,6 @@ M:Foundation.NSOrderedSet.#ctor(System.String[])
|
|||
M:Foundation.NSOrderedSet.Contains(System.Object)
|
||||
M:Foundation.NSOrderedSet.EncodeTo(Foundation.NSCoder)
|
||||
M:Foundation.NSOrderedSet.Equals(System.Object)
|
||||
M:Foundation.NSOrderedSet.GetEnumerator
|
||||
M:Foundation.NSOrderedSet.GetHashCode
|
||||
M:Foundation.NSOrderedSet.MakeNSOrderedSet``1(`0[])
|
||||
M:Foundation.NSOrderedSet.op_Addition(Foundation.NSOrderedSet,Foundation.NSOrderedSet)
|
||||
|
@ -33913,7 +33908,6 @@ M:Foundation.NSSet.#ctor(System.Object[])
|
|||
M:Foundation.NSSet.#ctor(System.String[])
|
||||
M:Foundation.NSSet.Contains(System.Object)
|
||||
M:Foundation.NSSet.EncodeTo(Foundation.NSCoder)
|
||||
M:Foundation.NSSet.GetEnumerator
|
||||
M:Foundation.NSSet.MakeNSObjectSet``1(`0[])
|
||||
M:Foundation.NSSet.op_Addition(Foundation.NSSet,Foundation.NSOrderedSet)
|
||||
M:Foundation.NSSet.op_Addition(Foundation.NSSet,Foundation.NSSet)
|
||||
|
|
|
@ -81,6 +81,17 @@ namespace MonoTouchFixtures.Foundation {
|
|||
Assert.AreEqual (C, lst.Count, "iterator count");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSArray<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNSObjectsNullTest ()
|
||||
{
|
||||
|
|
|
@ -233,5 +233,16 @@ namespace MonoTouchFixtures.Foundation {
|
|||
Assert.AreEqual (C, lst.Count, "iterator count");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSMutableArray<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -259,6 +259,17 @@ namespace MonoTouchFixtures.Foundation {
|
|||
Assert.AreEqual (C, lst.Count, "iterator count");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSMutableOrderedSet<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerableTest ()
|
||||
{
|
||||
|
|
|
@ -225,6 +225,17 @@ namespace MonoTouchFixtures.Foundation {
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSMutableSet<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerableTest ()
|
||||
{
|
||||
|
|
|
@ -179,6 +179,17 @@ namespace MonoTouchFixtures.Foundation {
|
|||
Assert.AreEqual (C, lst.Count, "iterator count");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSOrderedSet<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerableTest ()
|
||||
{
|
||||
|
|
|
@ -165,6 +165,17 @@ namespace MonoTouchFixtures.Foundation {
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerable1Test_EnumeratorType ()
|
||||
{
|
||||
var myEnumerable = new NSSet<NSNumber> ();
|
||||
foreach (var item in myEnumerable) {
|
||||
// The point of this test is to verify that the compiler finds the correct enumerator (the one returning NSNumbers, and not the one from the non-generic NSSet class returning NSObjects).
|
||||
// This means that we don't have to actually execute this code, it's enough to make it compile.
|
||||
Console.WriteLine (item.LongValue);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IEnumerableTest ()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче