Laden...

[erledigt] Größenvergleich zweier Produktversionen

Erstellt von Loomis vor 13 Jahren Letzter Beitrag vor 13 Jahren 1.130 Views
L
Loomis Themenstarter:in
63 Beiträge seit 2008
vor 13 Jahren
[erledigt] Größenvergleich zweier Produktversionen

Hallo,

ich stehe vor einem kleinen Problem, das ich bisher nur teilweise lösen konnte.
Ich versuche gerade 2 Versionsnummern zu vergleichen, um somit zu überprüfen, ob ein Programm updatebedürftig ist oder nicht.

Als Versionsnummer verstehe ich "1.0", "2.1.1330", "1.5RC2" u.s.w.

Nun habe ich den Ansatz, alle Zeichen ausser Zahlen aus den Strings zu entfernen und dann, konvertiert in Int64, einen normalen Größenvergleich zu machen:


            char[] character;

            this.character = new char[] { '.', ',', ';', 'A', 'B', 'C', 'D', 
                'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 
                'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 
                'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
                'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
                '/', '\\', '|', ' ', '!', '"', '§', '$', '%', '&', '/', '(', 
                ')', '=', '?', '´', '`', '-', '+', '*', 'Ä', 'Ö', 'Ü', 'ä', 
                'ö', 'ü'};

        /// <summary>
        /// Vergleicht 2 Strings mit ihrem Zahlenwert.
        /// </summary>
        /// <param name="groeßer">Der wahrscheinlich größere Wert.</param>
        /// <param name="kleiner">Der wahrscheinlich kleinere Wert.</param>
        /// <returns>Gibt true zurück, wenn größer > kleiner.</returns>
        private bool VergleicheObGroesser(string groeßer, string kleiner)
        {
            // Aus Strings mach Zahlen.
            foreach (char c in this.character)
            {
                groeßer = groeßer.Replace(c.ToString(), "");
                kleiner = kleiner.Replace(c.ToString(), "");
            }
            // Zahlen gleich lang machen.
            while (kleiner.Length > groeßer.Length)
                groeßer += "0";
            while (groeßer.Length > kleiner.Length)
                kleiner += "0";
            if (Convert.ToInt64(groeßer) > Convert.ToInt64(kleiner))
                return true;
            else
                return false;
        }


Die Methode funktioniert bis zu einer zweistelligen Version gut.

Z.B, wenn man "1.8.17" mit "1.9" vergleicht, wird daraus 1817 und 1900, also ist "1.9" größer.

Aber wenn man "24.0" mit "3.0" vergleicht, aus denen 240 und 300 wird, ist "3.0" unberechtigt größer.

Fällt einem da ein konkreter Lösungsvorschlag ein oder hab ich einfach ein Kapitel über String-Vergleiche übersprungen?

Noch eine kleine andere Frage; kann man die Variable character dynamischer mit Zeichen füllen?

2.891 Beiträge seit 2004
vor 13 Jahren

Guck dir mal http://code.google.com/p/wyupdate/source/browse/trunk/VersionTools.cs an. Da wurde genau sowas gemacht.

Ansonsten: Du musst jeweils an den Punkten trennen und dann die einzelnen Parts separat vergleichen. Wenn du noch zwischen "Alpha", "Beta", "RC1", "RC2" usw. vergleichen willst, musst du das dann auch noch betrachten.
Ist aber im obigen Code schon alles gemacht.

Gruß,
dN!3L

4.942 Beiträge seit 2008
vor 13 Jahren

Schau dir einfach mal die Klasse 'System.Version' und dessen Eigenschaften bzw. Operatoren an -)

2.891 Beiträge seit 2004
vor 13 Jahren

Schau dir einfach mal die Klasse 'System.Version' und dessen Eigenschaften bzw. Operatoren an -)

Gut, geht auch 😃
Kann aber nur Major, Minor, Build und Revision. Und kein Alpha, Beta, RC etc.

Gruß,
dN!3L

L
Loomis Themenstarter:in
63 Beiträge seit 2008
vor 13 Jahren

Sehr schön, 2 gute Alternativen, danke euch!

Ich werd wohl Verhaltensregeln einführen (RC u.s.w. blocken) und die System.Version benutzen, die ist wie dafür bestimmt 😉

1.373 Beiträge seit 2004
vor 13 Jahren

Nur so als Nachtrag, ich würde hier zwischen einer internen Versionsnummer und einer "Benutzerfreundlichen" Versionsnummer unterscheiden. Letztere würde Zusätze wie "alpha", "beta", und "RC1" enthalten, erstere wäre rein numerisch, z.B. 1.4.2.xxxx, wobei xxx Sachen wie alpha, beta, rc und rtm numerisch codiert (z.B. 1000=alpha, 2000=beta, 3000=rtm, 3001 = sp1 usw.). Das würde die von dir gewünschten Vergleiche natürlich wesentlich vereinfachen.

61 Beiträge seit 2009
vor 13 Jahren

Alternativ zum entfernen von Zeichen die keine Nummern sind (eigentlich sogar sinnvoller) finde ich persönlich Lamda-Ausdrücke.
Jedenfalls bin ich ein Freund von sowas 😉

z.B. so


string versionsString = "1.24";
string versionsnummer = // <== 124
     versionsString.Aggregate<char, string>(
               String.Empty, (s, c) => s += (Char.IsNumber(c) ? c.ToString() : String.Empty));

Das musste ich einfach loswerden 😁

Sonst ist System.Version das wohl beste.

In der Zeit vor fünf Minuten ist Jetzt die Zukunft. Jetzt ist die Gegenwart. Die Zeit, in der ich zu erzählen begonnen habe, ist die Vergangenheit von Jetzt und die Zukunft von der Gegenwart der Zeit, fünf Minuten bevor ich zu erzählen begann.

L
Loomis Themenstarter:in
63 Beiträge seit 2008
vor 13 Jahren

Ich hab meine Anwendung nun mit der Version-Klasse umgeändert.

Die Methode ist jetzt viel schicker 😄


        /// <summary>
        /// Vergleicht 2 Versionen im Format [Haupt.Neben[.Build.Revision]].
        /// </summary>
        /// <param name="groeßer">Die wahrscheinlich größere Version.</param>
        /// <param name="kleiner">Die wahrscheinlich kleinere Version.</param>
        /// <returns>groeßer KLEINER kleiner = -1, groeßer GLEICH kleiner = 0, groeßer GRÖßER kleiner = 1.</returns>
        private int VergleicheVersion(Version groeßer, Version kleiner)
        {
            return groeßer.CompareTo(kleiner);
        }

Gelöschter Account
vor 13 Jahren

2 verbesserungsvorschläge:

  1. verwende nciht als variablennamen "größer" oder "kleiner". in so einem fall verwendet man "left" und "right". du weißt ja nciht welches größer oder kleiner ist...

  2. die klasse "Version" unterstützt alle vergleichsoperatoren. daher ist deine art des vergleiches unnötig. du kannst ja jederzeit das da amchen:


myVersion1 > myVersion2

so wie mit allen anderen vergleichs-operatoren...