Frage

Hier ist, was ich tun möchte:

XmlWriter writer = XmlWriter.Create(
    (string.IsNullOrEmpty(outfile) ? Console.Out : outfile)
);

Dies ist jedoch nicht kompilieren, was die Fehler „Typ des bedingten Ausdrucks kann nicht bestimmt werden, weil es keine implizite Konvertierung zwischen‚System.IO.TextWriter‘und‚string‘“. Der obige Code ist eine Vereinfachung der folgenden Optionen:

XmlWriter writer;

if (string.IsNullOrEmpty(outfile))
{
    writer = XmlWriter.Create(Console.Out); // Constructor takes TextWriter
}
else
{
    writer = XmlWriter.Create(outfile); // Constructor takes string
}

Diese beiden Anrufe zu Create sind perfekt gültig, und das kompiliert wird. Gibt es eine Möglichkeit, dies kompakter zu machen, wie ich versuche, mit meinem Inline-Test zu tun?

Es macht keinen Sinn für mich machen, was ich will nicht funktioniert. Geistlich durch das Denken, so scheint es, wie der Compiler würde beurteilen string.IsNullOrEmpty(outfile) zu bestimmen, welcher Fall zu übernehmen:

  • Wenn die Bedingung wahr wäre, es mit Console.Out gehen würde, und dann sehen, dass es die Version von XmlWriter.Create zu polymorph wählen muss, die eine Textwriter nimmt.
  • Wenn die Bedingung falsch war, es mit outfile gehen würde, und dann sehen, dass es die Version von XmlWriter.Create zu polymorph wählen muss, die einen String.

Hat Programmierung in ML verzogen mein Gehirn?

War es hilfreich?

Lösung

Der Grund, warum Sie kann das nicht tun, weil der Compiler die Überlastung wählen muss erstellen bei der Kompilierung verwenden - Ihr Ansatz erfordern würde es zur Laufzeit durchgeführt werden. Der kürzeste Sie es machen kann, ist wahrscheinlich:

XmlWriter writer = String.IsNullOrEmpty(outfile)
    ? XmlWriter.Create(Console.Out)
    : XmlWriter.Create(outfile);

Andere Tipps

Jeder scheint folgender zu sein was darauf hindeutet:

XmlWriter writer = String.IsNullOrEmpty(outfile)
    ? XmlWriter.Create(Console.Out)
    : XmlWriter.Create(outfile);

Dies ist jedoch auch machbar:

XmlWriter writer = XmlWriter.Create(string.IsNullOrEmpty(outfile)
    ? Console.Out : new StreamWriter(outfile));

Dieser ist näher an der ursprünglichen Versuch und IMO, kompakter.

Die C # Compiler wählt eine Methode zur Ausführung statisch während der Kompilierung. Die IL, die erzeugt wird, wenn Sie kompilieren ist ein Verweis auf ein bestimmtes Verfahren. Der Polymorphismus Teil zur Laufzeit kommt, wenn es entscheidet, was die Umsetzung dieser spezifischen Funktion auszuführen.

Ihr: Anweisung zur Laufzeit und als solche dem Compiler, welche Methode ausführen kann nicht herausfinden ausgewertet

.

Ändern auf diese und es wird funktionieren.

XmlWriter writer = string.IsNullOrEmpty(outfile) ? 
    XmlWriter.Create(Console.Out) :
    XmlWriter.Create(outfile);

Das Problem ist, dass Sie nicht bei der Kompilierung bestimmen können, was

(string.IsNullOrEmpty(outfile) ? Console.Out : outfile)

zurückkehren sollte. Wird es eine Zeichenfolge sein oder es wird ein Textwriter sein? Das kann nur zur Laufzeit bestimmt werden, damit die Compiler-Fehler, weil das? Betreiber hat bei der Kompilierung aufgelöst werden.

Das Beste, was Sie können herausbekommen würde wahrscheinlich sein:

XmlWriter writer = string.IsNullOrEmpty(outfile)
    ? XmlWriter.Create(Console.Out)
    : XmlWriter.Create(outfile);

Ein paar Dinge passieren hier.

Zuerst wird die „Ausnahme“ auftritt, weil der ternären Operator (tm), nicht da, wo Sie es verwenden. Das Problem ist, weil Sie einen einzelnen Ausdruck haben, die zwei verschiedene Arten zurückzukehren versucht, die nicht zu einem einzigen, gemeinsamen Basistyp (außer Objekt) gelöst werden können.

Ferner Ihre Konstruktorüberladungen nehmen wahrscheinlich zwei völlig verschiedene Arten, die nicht in irgendeiner Weise verbunden sind. Der C # -Compiler ist sehr, sehr smart, aber es ist nicht ganz , die smart.

Nein, müssen Sie zwei getrennte Anrufe tätigen, da sie zwei getrennte Konstrukteuren.

Welche nennen Überlastung wird bei der Kompilierung festgelegt, so dass Sie einen Datentyp zur Laufzeit nicht wählen unterschiedliche Überlastungen zu nennen.

Auch kann der bedingte Operator nur einen einzigen Datentyp zurückgeben, können Sie es nicht haben unterschiedliche Datentypen zurückgeben auf der Wahl abhängig.

C # ist statisch typisiert alle Polymorphismus Magie geschieht Zeit kompilieren. Und die Art Ihres bedingten Ausdrucks wird bei der Kompilierung nicht bekannt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top