13

Dieser Code:Warum sagt Resharper, "Co-Variante Array-Konvertierung von String [] zu Objekt [] kann Laufzeitausnahme bei Schreibvorgang verursachen" mit diesem Code?

comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray()); 

public static List<String> months = new List<String> 
{ 
    "Jan", 
    "Feb", 
    "Mar", 
    "Apr", 
    "May", 
    "Jun", 
    "Jul", 
    "Aug", 
    "Sep", 
    "Oct", 
    "Nov", 
    "Dec" 
}; 

Schaltet R # curmudgeon artig mit der Beschwerde, "Co-Variante Array Konvertierung von string [] zum Objekt [] kann dazu führen, Laufzeitausnahme auf Schreiboperation".

Eigentlich funktioniert dieser Code perfekt - das Kombinationsfeld ist mit den Monatswerten gefüllt; Worum geht es bei Resharper und was kann ich tun, um seine Zweifel zu lindern?

Wenn es einfach ist, dass die generische Liste schlechte Daten enthält, werde ich mich nicht darum kümmern - und wenn es jemals ein Problem gab, wäre es leicht genug, das Problem aufzuspüren.

+2

Ich denke, eine Möglichkeit, um es zu umgehen wäre eine 'List ' anstelle von 'List ' zu verwenden. –

Antwort

21

Die Methode comboBoxMonth.Items.AddRange erwartet einen object[] Parameter. months.ToArray() ist string[]. Eine Umwandlung von string[] zu object[] ist zwar zulässig, aber wenn die Methode versucht, Elemente des Arrays zu ändern, werden Laufzeitfehler ausgegeben. In diesem Fall nicht, so dass Sie die Warnung ignorieren können.

Wenn es Sie ärgert, können Sie ToArray<object>()

comboBoxMonth.Items.AddRange(UsageRptConstsAndUtils.months.ToArray<object>()); 

Es wird object[] zurückkehren verwenden und keine Besetzung benötigt.

+1

Was meinen Sie mit * wenn eine Methode versucht, Elemente des Arrays * zu modifizieren? Das Ändern eines bereits im Array vorhandenen Elements sollte kein Problem darstellen. –

+2

@YuvalItzchakov: Wenn die Methode versucht, eine Banane dem Element 1 eines Arrays von Objekten zuzuweisen, das wirklich ein Array von Strings ist, dann wird zur Laufzeit ein Fehler auftreten. Die Leute erwarten vernünftigerweise, dass das Zuordnen einer Banane zu einer Reihe von Objekten erfolgreich sein wird, aber es könnte nicht funktionieren. –

+0

@EricLippert Ja, ich verstehe, und das habe ich in meiner Antwort versucht zu vermitteln. Aber ich denke, es gibt Mehrdeutigkeit in dem Satz, der besagt, dass das Ändern bestehender Elemente eine Laufzeitausnahme verursachen würde. –

13

Ein Beispiel, das Problem zu demonstrieren:

void Main() 
{ 
    Animal[] animals = new Girafee[2]; 
    animals[0] = new Zebra(); 
} 

public class Animal { } 
public class Girafee : Animal { } 
public class Zebra : Animal { } 

Dieses eine ArrayTypeMismatchException zur Laufzeit werfen.

R # ist im Grunde Hinting Sie ein mögliches Problem der Tatsache, dass Sie eine string[] zu einem object[] sind zuweisen, die vollständig durch den Compiler erlaubt ist, kann aber auf eine Laufzeitausnahme, wenn ein Objekt führen, die teilt die gleiche Basisklasse, die dem Array zugewiesen ist, das bereits auf einen anderen Typ zeigt (wie in meinem Beispiel zeigen wir tatsächlich auf ein Girafee-Array). Array-Kovarianz ist in der Bedeutung gebrochen, dass es Ihnen nicht die Kompilierungssicherheit bietet, die Sie mit Generika erhalten.

Eric Lippert spricht über diese in Covariance and Contravariance in C#, Part Two: Array Covariance:

Leider ist diese besondere Art der Kovarianz ist gebrochen. Es wurde zur CLR hinzugefügt, da Java es erfordert und die CLR-Designer in der Lage waren, Java-ähnliche Sprachen zu unterstützen. Wir haben es dann hochgefahren und es zu C# hinzugefügt, weil es in der CLR war. Diese Entscheidung war ziemlich umstritten unter der Zeit und ich bin nicht sehr glücklich darüber, aber es gibt nichts, was wir darüber jetzt tun können.

Warum ist das kaputt? Denn es sollte immer legal sein, eine Turtle in ein Array von Tieren zu legen. Mit Array-Kovarianz in der Sprache und Runtime können Sie nicht garantieren, dass ein Array von Tieren eine Schildkröte akzeptieren kann, da die Backing-Store tatsächlich eine Anordnung von Giraffen sein könnte.

Verwandte Themen