10 Stimmen

Warum verwenden C#-Container und GUI-Klassen bei Größenangaben int anstelle von uint?

Normalerweise programmiere ich in C++, aber für die Schule muss ich ein Projekt in C# machen.

Also habe ich einfach weiter programmiert, wie ich es in C++ gewohnt war, war aber überrascht, als der Compiler sich über Code wie folgenden beschwerte:

        const uint size = 10;
        ArrayList myarray = new ArrayList(size); //Arg 1: kann von 'uint' nicht in 'int' konvertiert werden

Sie erwarten also einen Argumenttyp von int - aber warum? Mir würde es viel mehr zusagen, uint als Argumenttyp zu verwenden, da uint in diesem Fall viel besser passt.

Warum verwenden sie fast überall im .NET-Framework int als Argumenttyp, obwohl in vielen Fällen negative Zahlen keinen Sinn ergeben (weil keine Container oder GUI-Elemente eine negative Größe haben können).

Wenn der Grund dafür, dass sie int verwendet haben, darin liegt, dass sie nicht davon ausgehen, dass der durchschnittliche Benutzer auf Vorzeichen achten würde, warum haben sie dann keine Überladungen für uint hinzugefügt?

Handelt es sich hierbei einfach um Microsoft, denen die Korrektheit des Vorzeichens egal ist, oder gibt es Fälle, in denen negative Werte Sinn ergeben / Informationen tragen (Fehlercode????) für Container/Gui-Widgets/... Größen?

0 Stimmen

Ich habe mich bereits über die gleiche Tatsache gewundert und keine Antwort gefunden.

12voto

Andrew Hare Punkte 332190

Ich würde vermuten, dass Microsoft Int32 gewählt hat, weil UInt32 nicht CLS-konform ist (d.h. nicht alle Sprachen, die das .NET-Framework verwenden, unterstützen vorzeichenlose Ganzzahlen).

0 Stimmen

Immer hätten sie einige Meta-Attribute hinzufügen sollen, um die implizite Konvertierung von uint in int in diesen Fällen (nur) zu unterstützen, das Fehlen von so etwas macht uint ziemlich wertlos, wenn man mit .NET arbeitet

2voto

Hans Passant Punkte 894572

Weil vorzeichenlose Ganzzahlen nicht CLS-konform sind. Es gibt Sprachen, die keine Unterstützung dafür haben, Java wäre ein Beispiel.

2voto

Ben M Punkte 21694

Additionaly to the Responses Talking about CLS Compliance, Bedenke, dass Ganzzahlenarithmetik (z.B. 10 + 2) zu Ganzen (vorzeichenbehafteten) Daten führt, was nur sinnvoll ist; Bedenke nun den Aufwand, jede mathematische Ausdruck in uint umwandeln zu müssen, um ihn an eine der von dir genannten Methoden zu übergeben.

Was Überladungen betrifft, die uint akzeptieren - in vielen Fällen werden Methodenargumente als (oder zur Berechnung von) Eigenschaftswerten gespeichert, die normalerweise vom Typ int sind (wieder für CLS-Konformität und möglicherweise für den Komfort der Ganzzahlenrechnung); die Diskrepanz im Vorzeichen wäre verwirrend, ganz zu schweigen von der Anfälligkeit für Überlauf.

1 Stimmen

Wenn Sie Arithmetik mit uints durchführen, ist das Ergebnis auch ein uint. Details finden Sie im Abschnitt 7.7 der C# 3-Spezifikation. Es ist wahr, dass Integer Literale standardmäßig int sind, aber diese Entscheidung hätte auch anders getroffen werden können.

0 Stimmen

@Jon Skeet: Du hast recht, ich habe mich auf Literale bezogen. Ich verstehe es vielleicht falsch, aber du scheinst zu suggerieren, dass uint-Literale eine geeignete Alternative wären. Ich nehme an, du meinst theoretisch, nicht praktisch -- da wir sonst viele verwirrte neue C#-Entwickler hätten, ganz zu schweigen von einer Menge an Castings.

0 Stimmen

Ich meine, dass C# so hätte entworfen werden können, dass positive Literale standardmäßig zu uint anstatt int würden. Es ist natürlich viel zu spät, um es jetzt zu ändern.

0voto

Conrad Albrecht Punkte 1798

Stroustrup bevorzugt int gegenüber "uint" in The C++ Programming Language, und ich denke, seine Gründe gelten auch für C#:

Es geht um Unterlauf ohne Warnung:

// Versehentlich sehr große uint
uint oops = (uint)5 - (uint)10;

oder:

// Versehentliche Endlosschleife
for( uint counter = 10; counter >= 0; counter-- )
    ;  // Etwas tun

Die zusätzliche Info ist selten den Aufwand wert, auf solche Fehler achten zu müssen.

0 Stimmen

C# kann eine Ausnahme bei Unter- oder Überlauf auslösen (sofern über die Projekt-Einstellungen aktiviert), daher scheint dies kein gültiges Argument zu sein.

0voto

Alejandro Punkte 6720

Dies kommt möglicherweise ein "wenig" spät, aber ich habe die Frage gerade gefunden und möchte ein fehlendes Detail hinzufügen.

Ein ausgezeichnetes Beispiel, in dem negative Werte perfekt Sinn ergeben, sind grafische Frameworks. Für Größen, wie in der Frage angegeben, kommen negative Werte nicht infrage, aber für Position Werte ist es durchaus akzeptabel, negative Werte zu haben. Solche Werte lassen Objekte erscheinen, die außerhalb des Bildschirms liegen oder zumindest teilweise beschnitten sind: Steuerung mit negativem Positions-Wert

Es folgt dem gleichen Prinzip wie in der Mathematik, negative Koordinaten lassen Punkte in die entgegengesetzte Richtung zu der Achse wachsen Werte gehen. Unter der Annahme, dass (0,0) oben links in der Ecke des Bildschirms ist, verschieben negative Werte Dinge nach links und oben von diesem Punkt, sodass sie halb sichtbar sind.

Dies ist nützlich zum Beispiel, wenn Sie einen Scroll-Bereich implementieren möchten, bei dem die Inhalte größer sind als der verfügbare Platz. Einfach alle Objektpositionen werden negativ, um vom oberen Rand unsichtbar zu werden oder größer als die Höhe zu werden, um vom unteren Rand unsichtbar zu werden.

Solche Dinge sind nicht auf C# beschränkt. Winforms und WPF verwenden das, wie in der Frage erwähnt, aber die meisten anderen grafischen Umgebungen verhalten sich genauso. HTML+CSS können Elemente auf die gleiche Weise platzieren, oder die C/C++ Bibliothek SDL kann diesen Effekt ebenfalls nutzen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X