Der Vertrag auf Stream.Read ist etwas, das ich bei vielen Menschen beobachtet habe:
// Read 8 bytes and turn them into a ulong
byte[] data = new byte[8];
stream.Read(data, 0, 8); // <-- WRONG!
ulong data = BitConverter.ToUInt64(data);
Der Grund dafür, dass dies falsch ist, liegt darin, dass Stream.Read
wird lesen allenfalls die angegebene Anzahl von Bytes, ist aber völlig frei nur 1 Byte zu lesen, auch wenn vor dem Ende des Streams noch 7 Bytes zur Verfügung stehen.
Es hilft auch nicht, dass es so ähnlich aussieht wie Stream.Write
die es garantiert, dass er alle Bytes geschrieben hat, wenn er ohne Ausnahme zurückkehrt. Es hilft auch nicht, dass der obige Code funktioniert fast immer . Und natürlich hilft es auch nicht, dass es keine fertige, bequeme Methode gibt, um genau N Bytes korrekt zu lesen.
Um die Lücke zu schließen und das Bewusstsein für diese Problematik zu schärfen, hier ein Beispiel für eine korrekte Vorgehensweise:
/// <summary>
/// Attempts to fill the buffer with the specified number of bytes from the
/// stream. If there are fewer bytes left in the stream than requested then
/// all available bytes will be read into the buffer.
/// </summary>
/// <param name="stream">Stream to read from.</param>
/// <param name="buffer">Buffer to write the bytes to.</param>
/// <param name="offset">Offset at which to write the first byte read from
/// the stream.</param>
/// <param name="length">Number of bytes to read from the stream.</param>
/// <returns>Number of bytes read from the stream into buffer. This may be
/// less than requested, but only if the stream ended before the
/// required number of bytes were read.</returns>
public static int FillBuffer(this Stream stream,
byte[] buffer, int offset, int length)
{
int totalRead = 0;
while (length > 0)
{
var read = stream.Read(buffer, offset, length);
if (read == 0)
return totalRead;
offset += read;
length -= read;
totalRead += read;
}
return totalRead;
}
/// <summary>
/// Attempts to read the specified number of bytes from the stream. If
/// there are fewer bytes left before the end of the stream, a shorter
/// (possibly empty) array is returned.
/// </summary>
/// <param name="stream">Stream to read from.</param>
/// <param name="length">Number of bytes to read from the stream.</param>
public static byte[] Read(this Stream stream, int length)
{
byte[] buf = new byte[length];
int read = stream.FillBuffer(buf, 0, length);
if (read < length)
Array.Resize(ref buf, read);
return buf;
}
158 Stimmen
Return DateTime.Now.AddDays(1);
24 Stimmen
Soweit ich weiß, sind die eingebauten Werttypen alle unveränderlich, zumindest insofern, als jede Methode, die mit dem Typ verbunden ist, ein neues Element zurückgibt, anstatt das vorhandene Element zu verändern. Zumindest fällt mir spontan kein Typ ein, der dies nicht tut: alles schön und konsistent.
1 Stimmen
Community-Wiki, so viel Spam in SO jetzt. Wenn Fragen subjektiv sind (keine endgültige Antwort), sollte es Community Wiki sein.
6 Stimmen
Veränderlicher Werttyp: System.Collections.Generics.List.Enumerator :( (Und ja, Sie können sehen, dass es sich seltsam verhält, wenn Sie sich genug Mühe geben).
0 Stimmen
Lol, ich wusste, dass es Ausnahmen geben würde. Enumerator scheint irgendwie... s
14 Stimmen
T
22 Stimmen
N
4 Stimmen
T
4 Stimmen
D
2 Stimmen
Sollte genannt werden
dt.NextDays(1);
haben die Programmierer keine Ahnung, dass er seinen eigenen Wert ändert. Genauso wie bei Datenstrukturkonstrukten (z.B.node->next
,node.next
) ändert den Wert von node nicht. Und jetzt ist es zu spät, sie könntendt.AddDays(1)
die Semantik, dass sie Tage in ihrem eigenen Wert hinzufügen.1 Stimmen
Ich stimme zu, dass es sich bei dem genannten Beispiel um eine Frage der Namensgebung handelt. Der Name der Methode impliziert, dass sie zum Datum addiert wird. Etwas wie
dt.PlusDays(1)
wäre klarer. Ein weiteres Problem bei dieser Methode ist, dass sie nur einedouble
Wert, so dass das Ergebnis nicht exakt ist.0 Stimmen
Ich würde diese Frage gewinnen, wenn eine dumme Person dieses Thema nicht geschlossen hätte. Ich kenne den bösesten Bug der Welt. Bitte sehen Sie codeproject.com/Feature/
1 Stimmen
@bluefeet, da die Benutzer >= 62 Antworten gegeben haben (einschließlich Jon Skeet), viele davon mit Hunderten von Bewertungen, dann wollen die Benutzer offenbar auch diese Art von Fragen. Entweder handelt es sich hier um eine angemessene Art von Fragen, oder es ist Zeit für eine Verfassungsänderung aller einschränkenden Regeln von SO.
0 Stimmen
5.add(2); 5 sollte immer noch 5 sein.