384 Stimmen

Was ist der schlimmste Fehler in C# oder .NET?

Ich habe kürzlich mit einem DateTime Objekt, und schrieb etwas wie dieses:

DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?

Die Intellisense-Dokumentation für AddDays() sagt, dass es einen Tag zum Datum hinzufügt, was nicht der Fall ist - es devuelve ein Datum mit einem hinzugefügten Tag, also müssen Sie es so schreiben:

DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date

Dies hat mich schon einige Male gebissen, also dachte ich, es wäre nützlich, die schlimmsten C#-Fehler zu katalogisieren.

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.

2voto

Shaul Behr Punkte 35201

LINQ to SQL und One-To-Many-Beziehungen

Das ist eine schöne Sache, die mich schon ein paar Mal gebissen hat, und MS überließ es einem ihrer eigenen Entwickler, sie einzubauen ihr Blog . Ich kann es nicht besser ausdrücken, als sie es getan hat, also schauen Sie dort nach.

2voto

Shekhar_Pro Punkte 17558

Ich dachte immer value Typen waren immer an stack y reference Typen auf heap .

Nun, es ist nicht so . Als ich sah diese Frage Kürzlich habe ich bei SO erfahren, dass das nicht der Fall ist (und habe wohl falsch geantwortet).

Als Jon Skeet beantwortet (mit einem Hinweis auf Eric Lippert's Blogbeitrag ) sein ein Mythos .

Erheblich wichtige Links:

Die Wahrheit über Werttypen

Referenzen sind nicht aAddress

Der Stapel ist ein Implementierungsdetail Teil 1

Der Stapel ist ein Implementierungsdetail Teil 2

1voto

SkeetJon Punkte 1471

Übergabe einer Kapazität an List<int> anstatt den Initialisierer der Sammlung zu verwenden.

var thisOnePasses = new List<int> {2}; // collection initializer
var thisOneFails = new List<int> (2);  // oops, use capacity by mistake #gotcha#

thisOnePasses.Count.Should().Be(1);
thisOnePasses.First().Should().Be(2);

thisOneFails.Count.Should().Be(1);     // it's zero
thisOneFails.First().Should().Be(2);   // Sequence contains no elements...

1voto

Chuu Punkte 3941

Nicht die schlechteste, aber eine, die noch nicht erwähnt wurde. Factory-Methoden, die als Argumente an System.Collections.Concurrent-Methoden übergeben werden, können mehrfach aufgerufen werden, auch wenn nur ein Rückgabewert verwendet wird. Wenn man bedenkt, wie sehr .NET versucht, Sie vor ungewolltem Aufwachen in Threading-Primitiven zu schützen, kann dies eine Überraschung sein.

using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ValueFactoryBehavingBadlyExample
{
    class Program
    {
        static ConcurrentDictionary<int, int> m_Dict = new ConcurrentDictionary<int, int>();
        static ManualResetEventSlim m_MRES = new ManualResetEventSlim(false);
        static void Main(string[] args)
        {
            for (int i = 0; i < 8; ++i)
            {
                Task.Factory.StartNew(ThreadGate, TaskCreationOptions.LongRunning);
            }
            Thread.Sleep(1000);
            m_MRES.Set();
            Thread.Sleep(1000);
            Console.WriteLine("Dictionary Size: " + m_Dict.Count);
            Console.Read();
        }

        static void ThreadGate()
        {
            m_MRES.Wait();
            int value = m_Dict.GetOrAdd(0, ValueFactory);
        }

        static int ValueFactory(int key)
        {
            Thread.Sleep(1000);
            Console.WriteLine("Value Factory Called");
            return key;
        }
    }
}

(Mögliche) Ausgabe:

Value Factory Called
Value Factory Called
Value Factory Called
Value Factory Called
Dictionary Size: 0
Value Factory Called
Value Factory Called
Value Factory Called
Value Factory Called

1voto

guruprasath Punkte 267

Manchmal stimmen die Zeilennummern im Stacktrace nicht mit den Zeilennummern im Quellcode überein. Dies kann durch das Inlining von einfachen (einzeiligen) Funktionen zur Optimierung geschehen. Dies ist eine ernsthafte Quelle der Verwirrung für Leute, die mit Hilfe von Protokollen debuggen.

Edit: Beispiel: Manchmal sieht man eine Nullreferenz-Ausnahme im Stacktrace, wo sie auf eine Codezeile verweist, bei der absolut keine Chance auf eine Nullreferenz-Ausnahme besteht, wie z. B. bei einer einfachen Ganzzahlzuweisung.

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