Frage

Dies scheint eine Menge in meinem Code zu kommen, ich frage mich, ob es irgendeine Art und Weise des Entfernens der switch-Anweisung ist, oder wenn es eine elegantere Möglichkeit, es zu tun?

    public class MetaData
{
    public string AlbumArtist { get; set; }
    public string AlbumTitle { get; set; }
    public string Year { get; set; }
    public string SongTitle { get; set; }


    public static MetaData CreateMetaDataFrom(IEnumerable<TextFrame> textFrames)
    {
        var metaData = new MetaData();

        foreach (var frame in textFrames)
        {
            switch (frame.Descriptor.ID)
            {
                case "TPE1":
                    metaData.AlbumArtist = frame.Content;
                    break;

                case "TALB":
                    metaData.AlbumTitle = frame.Content;
                    break;

                case "TIT2":
                    metaData.SongTitle = frame.Content;
                    break;

                case "TYER":
                    metaData.Year = frame.Content;
                    break;
            }
        }

        return metaData;
    }
}
War es hilfreich?

Lösung

Von Ihrem Code, den ich schließen, dass IEnumerable hat immer 4 Mitglieder so könnte man einfach schreiben (habe nicht versucht, es so für die Syntaxprüfung):

public static MetaData CreateMetaDataFrom(IEnumerable<TextFrame> textFrames)
{
    return new MetaData()
    {
        metaData.AlbumArtist = textFrames.Where(frame => frame.Descriptor.ID = "TPE1").SingleOrDefault().Content,
        metaData.AlbumTitle = textFrames.Where(frame => frame.Descriptor.ID = "TALB").SingleOrDefault().Content, 
        metaData.SongTitle = textFrames.Where(frame => frame.Descriptor.ID = "TIT2").SingleOrDefault().Content;
        metaData.Year = textFrames.Where(frame => frame.Descriptor.ID = "TYER").SingleOrDefault().Content;
    };
}

Andere Tipps

Dies ist auf einen objektorientierten Ansatz zusammen. Die übliche Methode, um loszuwerden, wenn der oder Fall ist, ist eine Verweistabelle von Kriterien und Effekte zu nutzen. Es gibt noch andere Techniken, die diese gleiche Idee, wie datengesteuerte Programmierung verwenden ( http: // en .wikipedia.org / wiki / Daten-directed_programming ) und Versendetabellen ( http: // en .wikipedia.org / wiki / Dispatch_table ). Viele Sprach Implementierungen verwenden Typ Versendetabellen auf virtuelle Methodenaufrufe zu implementieren.

Die Nachschlagtabelle eine Hash-Tabelle bevölkert mit Lambda-Funktionen werden könnte, wie so:

Dictionary<string, Func<MetaData, string, string>> lookup = new Dictionary<string, Func<MetaData, string, string>>();
lookup["TPE1"] = (m, v) => m.AlbumArtist = v;
lookup["TALB"] = (m, v) => m.AlbumTitle = v;
lookup["TIT2"] = (m, v) => m.SongTitle = v;
lookup["TYER"] = (m, v) => m.Year = v;

dann weisen Sie Felder metaData innerhalb der Schleife wie:

lookup[frame.Descriptor.ID](metaData, frame.Content);

Sie könnten bei der Umsetzung der Strategie-Muster zu suchen. DimeCasts.Net ein exzellenten Video-Tutorial, die helfen können.

Ich war versucht, die Strategie-Muster vorschlagen Sie können jedoch eine leichte Variation benötigen. Betrachten Sie eine Methode in der Klasse Textframe zu schreiben, es lässt nennen putContent (Metadaten).

Dann Subklassen von Textframe erstellen jeweils eine andere Art des Rahmens darstellt. Jede Unterklasse wird das putContent (Metadaten) -Methode außer Kraft setzen und seine appropraite Logik tun.

Pseudo-Code Beispiel für TPE1:

 Metadata putContent(MetaData md){
       md.AlbumArtist = Content;
       return md;
 }

Sie MetaDaten Code wird dann ändern:

var metaData = new MetaData();

    foreach (var frame in textFrames)
    {
           metaData = frame.putContent(metaData);
    }
 return metaData;

Natürlich die Textframes, sie selbst zu schaffen, wird dann eine Fabrik benötigen, so ist dies nicht das Ende der Geschichte.

Es scheint, wie Sie wissen, was die Typen vor Ort sein werden (mit einem Schalter) warum also nicht nur die Werte abrufen je nach Bedarf, ohne einen für den Schalter.

Beispiele dafür sind eine Hash-Tabelle verwendet, und Sie wissen, welche Felder zur Verfügung stehen werden, um nur die Felder verwenden.

ig Sie nicht sicher sind, ob das Feld verfügbar ist, wird ein einfacher Test vollkommen ausreichend, wenn die Liste den Wert enthält.

Sie können dann schreiben sogar eine Hilfsfunktion den Wert zu überprüfen und zurück, wenn die Liste den Wert.

Was Sie wirklich hier haben, ist ein Vier-Wege-Setter. Das kanonische Refactoring hier ist "Parameter Ersetzen mit expliziten Methoden" (p285 von Refactoring von Martin Fowler). Das Java-Beispiel gibt er verändert sich:

void setValue(String name, int value) {
  if (name.equals("height")) {
    _height = value;
    return;
  }
  if (name.equals("width")) {
    _width = value;
    return;
  }
}

zu:

void setHeight(int arg) {
  _height = arg;
}

void setWidth(int arg) {
  _width = arg;
}

Unter der Annahme, dass der Anrufer von CreateMetaDataFrom() weiß, was drin ist vorbei, können Sie die switch/case überspringen könnte und die tatsächlichen Setter für diese Eigenschaften verwendet werden.

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