2016-06-15 11 views
1

Ich möchte wissen, ob eine der Klassen in der .NET-Framework, die IEnumerable implementieren die ICollection-Schnittstelle nicht implementiert.konkrete Implementation von IEnumerable <T> das ist nicht ICollection <T>

Ich frage, weil ich nicht zu 100% Codeabdeckung in der folgenden Erweiterung Methode, die ich geschrieben bekommen:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollaction) 
    { 
     if (nullableCollaction == null) 
     { 
      return 0; 
     } 
     var collection = nullableCollaction as ICollection<T>; 
     if (collection != null) 
     { 
      return collection.Count; 
     } 
     return nullableCollaction.Count(); 
    } 

Die letzte Zeile ist nicht in jedem meiner Tests abgedeckt und ich kann‘ Ich finde die richtige Klasse, um sie zu instanziieren.

mein Testcode ist:

[Test] 
    public void GetSafeCount_NullObject_Return0() 
    { 
     IEnumerable<string> enumerable=null; 

     Assert.AreEqual(0, enumerable.GetSafeCount()); 
    } 
    [Test] 
    public void GetSafeCount_NonICollectionObject_ReturnCount() 
    { 
     IEnumerable<string> enumerable = new string[]{}; 

     Assert.AreEqual(0, enumerable.GetSafeCount()); 
    } 
+0

Ist das nicht schon "Enumerable.Count()"? –

+1

@PanagiotisKanavos: Nein, denn wenn das Argument für "Enumerable.Count" null ist, wird eine Ausnahme ausgelöst. –

+0

@JonSkeet dann ist nur der Null-Check notwendig. Der Rest des Codes kann entfernt werden. Der Komponententest müsste nur auf korrekte Nullbehandlung überprüfen –

Antwort

1

Sie die Stack<T> Klasse verwenden können, implementiert es ICollection und IEnumerable<T> aber nicht ICollection<T>.

Hier ist, wie die Klasse definiert ist:

public class Stack<T> : IEnumerable<T>, IEnumerable, ICollection, 
    IReadOnlyCollection<T> 
+0

aber es ist auch kein IEnumerable silver

+0

@silver, es ist 'IEnumerable '. Sie können den von mir bereitgestellten MSDN-Dokumentationslink überprüfen. –

+0

Sie haben Recht! Vielen Dank!!! – silver

2

Verwenden Sie einfach eine beliebige LINQ Betrieb, zum Beispiel Where:

[Test] 
public void GetSafeCount_NonICollectionObject_ReturnCount() 
{ 
    IEnumerable<string> enumerable = new string[0].Where(x => x.Length == 0); 
    Assert.AreEqual(0, enumerable.GetSafeCount()); 
} 

jedoch Sie Ihre Implementierung von nur Aufschieben zu Enumerable.Count() vereinfachen kann, was ich erwarten würde jede Art und Weise optimiert werden Sie es sein möchten:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollection) 
    => nullableCollection == null ? 0 : nullableCollection.Count(); 

Oder:

public static int GetSafeCount<T>(this IEnumerable<T> nullableCollection) 
    => nullableCollection?.Count() ?? 0; 

(Beide gehen davon aus C# 6 ...)

Zu diesem p In diesem Fall ist es sinnvoll, nur zwei Tests zu verwenden: einen für ein Null-Argument, einen für ein Nicht-Null-Argument.

0

Er ist ein Beispiel für eine IEnumerable<T>, der kein ICollection<T> ist:

public class MyClass : IEnumerable<int> 
{ 
    public List<int> ints = new List<int> { 1, 2, 3, 4, 5 }; 

    public IEnumerator<int> GetEnumerator() 
    { 
     foreach (var i in ints) 
     { 
      yield return i; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this as IEnumerator; 
    } 
} 

Jetzt können Sie dies tun:

foreach(var item in new MyClass()) 
{ 
    // do something 
} 

Aber kann dies nicht tun, da es kein ICollection ist

var coll = new MyClass() as ICollection<int>; // null!!! 
Verwandte Themen