2016-04-01 30 views
1

Ich versuche, meine eigene Sammlung zu schreiben. Es enthält natürlich generische Werte. Wenn ich versuche zu überprüfen, ob der Wert des Arrays _content nicht null ist - funktioniert es gut, aber nur, wenn der Benutzer keine Ganzzahlen verwendet.Überprüfen, ob generic 0 ist

Der Punkt ist, dass Benutzer Sammlung von ganzen Zahlen erstellen können und als Array alle Werte als 0 initialisiert werden. Also, wenn ich versuche zu überprüfen, ob der Wert 0 ist - es kompiliert nicht.

if (_content[_size - 1] != 0) 

Insbesondere diese Methode nicht funktioniert (wenn Sammlung von ganzen Zahlen besteht):

public void Add(T item) 
{ 
     if (_content[_size - 1] != null) 
      throw new ArgumentOutOfRangeException("The Array is full"); 
     if (_size > 0) 
     { 
      for (int i = 0; i <= _size; i++) 
      { 
       if (_content[i] == null) 
       { 
        _content[i] = item; 
        break; 
       } 
      } 
     } 

} 
+0

Was sind Sie mit Ihrer neuen Kollektion zu tun versuchen? Sie können es vielleicht einfacher mit etwas eingebautem umgehen. – zimdanen

+1

suchen Sie nach 'default (T)'? – Jonesopolis

+0

Hinzufügen funktioniert nicht. Ich habe es gerade zur Beschreibung hinzugefügt. –

Antwort

1

Sie die default Schlüsselwort auf generische Typen verwenden können, es gibt den der Standardwert dieses Typs (dh Null für Referenztypen, 0 oder falsch usw. für Werttypen).

Edit: Zurück Beispiel würde abstürzen :-)

So versuchen:

!object.Equals(_content[_size - 1], default(T)) 

Siehe Anmerkungen für einen anderen zu Lösung.

1

Sie können das default Schlüsselwort überprüfen, ob ein Wert den Standard seiner Art entspricht, dh null für Klassen, 0 für Zahlen usw.

Sie müssen auch Object.Equals(a,b) oder EqualityComparer<T>.Default.Equals() als == Operator isn verwenden‘ t garantiert auf der Klasse T verfügbar sein, so wird es nicht kompilieren.

So könnte Ihre Methode in etwa so aussehen:

public void Add(T item) 
{ 
    if (!EqualityComparer<T>.Default.Equals(_content[_size - 1], default (T))) 
     throw new ArgumentOutOfRangeException("The Array is full"); 
    if (_size > 0) 
    { 
     for (int i = 0; i <= _size; i++) 
     { 
      if (EqualityComparer<T>.Default.Equals(_content[i], default (T))) 
      { 
       _content[i] = item; 
       break; 
      } 
     } 
    } 
} 
0

Das Problem, das Sie Überprüfung auf null bekommen ist, dass Werttypen (structs, ganze Zahlen ETCs) können nicht mit null verglichen werden.

Sie können hier ein paar verschiedene Ansätze verfolgen. Eine besteht darin, die Typen einzuschränken, die mit der generischen Erfassungsklasse verwendet werden können. Auf diese Weise können Sie sicherstellen, dass nur NULL-Typen (d. H. Referenztypen) als Typdefinitionen für die Sammlung verwendet werden.

public class MyCollection<T> where T : class

Oder Sie können prüfen, ob der Typ ein Typ vor Bezug ist es auf null zu vergleichen, die die Reflexion:

typeof(T).IsValueType

überprüfen Sie nicht für bestimmte Arten - Ihr Problem hier ist, dass Sie Nicht-Nullable-Typen mit null vergleichen.

7

Was Sie versuchen, ist eine schlechte Praxis, also tun Sie es nicht.

Ihr Ansatz reserviert einen Wert, nämlich Null, um "nichts" darzustellen. Es gibt jedoch einen Unterschied zwischen Null und Nichts, daher würde Ihr Ansatz zu Fehlern führen, wenn Null ein zulässiger Wert ist.

Überlegen Sie, was passieren würde, wenn der Benutzer Ihrer Sammlung Null für die letzte Nummer hinzufügt. Ihr Code würde denken, dass die Zelle leer ist, und die Ausnahme nicht so werfen, wie sie sollte.

Ein besserer Ansatz wäre, die tatsächliche Anzahl der Elemente zu speichern, die in der Sammlung in Ihrem Feld _size festgelegt wurden. Das letzte Element von _content liegt verkehrsgünstig an _content.Length-1 gelegen, so könnte Ihr Scheck erfolgen wie folgt:

if (_content.Length == _size) { 
    // InvalidOperationException is more appropriate here, 
    // because the error is caused by the state of your collection, 
    // rather than any particular argument passed to the method. 
    throw new InvalidOperationException("The Array is full"); 
}