C# Language Gotcha: restituire la risorsa che si sta smaltendo


Esempio

La seguente è una cattiva idea perché eliminerebbe la variabile db prima di restituirla.

public IDBContext GetDBContext()
{
    using (var db = new DBContext())
    {
        return db;
    }
}

Questo può anche creare errori più sottili:

public IEnumerable<Person> GetPeople(int age)
{
    using (var db = new DBContext())
    {
        return db.Persons.Where(p => p.Age == age);
    }
}

Questo sembra ok, ma il problema è che la valutazione delle espressioni LINQ è DBContext e probabilmente verrà eseguita solo in un secondo momento, quando il DBContext sottostante è già stato eliminato.

Quindi in breve l'espressione non viene valutata prima di lasciare l' using . Una possibile soluzione a questo problema, il che rende ancora uso di using , è di indurre l'espressione di valutare immediatamente chiamando un metodo che enumerare il risultato. Ad esempio ToList() , ToArray() , ecc. Se si utilizza la versione più recente di Entity Framework, è possibile utilizzare le controparti async come ToListAsync() o ToArrayAsync() .

Di seguito trovi l'esempio in azione:

public IEnumerable<Person> GetPeople(int age)
{
    using (var db = new DBContext())
    {
        return db.Persons.Where(p => p.Age == age).ToList();
    }
}

È importante notare, tuttavia, che chiamando ToList() o ToArray() , l'espressione verrà valutata con entusiasmo, il che significa che tutte le persone con l'età specificata verranno caricate in memoria anche se non si esegue iterazione su di esse.