ordellMedlem sedan sep. 200278 inlägg Jag skrev lite kod för att plocka upp ett värde från sessionstate häromdagen (ett lagrat enumvärde). Jag kom på följande idé och jag vill lite feedback på den.
Eftersom Sessionobjektet kommer att returnera null om nyckeln inte finns måste man alltid se till det finns innan man försöker hämta upp objektet i samlingen (inget konstigt med det). Koden skulle se ut ungefär så här med en enum som vi kallar Vechicles med Car, Boat och NotSet, utan att kolla att det lagrade värdet i själva verket av enum-typ.
Vehichle vechicle = Vehicle.NotSet;
if (Session ["VehicleUsed"]! = null)
(
vechicle = (Vechicle)Session["VehicleUsed"];
)
// Gör något med enumvärdet ...
Men, om jag skulle använda null coalsecing, nullable typer och ett as-nyckelord för att se till att värdet som finns? Koden skulle se ut så här:
Vehicle vechicle = Session ["VehicleUsed"] as Vechicle? ?? Vehicle.NotSet;
/ / Gör något med enumvärdet ...
Detta skulle garantera att värdet är alltid satt även om sessionen är tom eller nyckeln inte finns. Det ser också till att objektet förvaras i staten är av rätt typ eftersom nyckelordet as skulle returnera null annars, eller hur? Koden fungerar och jag tycker att det är mycket smidigare än den med if-satsen ovan.
Så, vad jag undrar är ... hur är det med prestanda? Andra tankar?
(jag skrev detta på engelska och postade på ett annat forum, använde Google Translate och ändrade texten lite eftersom jag inte orkade skriva om från börja, eventuella språkliga fel kan ha hittat in i texten, jag ber om ursäkt :-))
Ditt sista förslag kommer inte påverka prestandan (inte märk bart, det som händer är att du får ett objekt i heapen). Du får väga om Robustness är större än correctness. Robert C. Marin skriver i sin bok Clean Code:
"When we return null, we are essentially creating work for ourselves and foisting problems upon our callers. All it takes is one missing null check to send an application spinning out of control."
BrimbaMedlem sedan dec. 19995 875 inlägg Båda fungerar säkert bra precis som du säger, men jag kan tycka att ditt sista exempel ofta tenderar att bli mer svårläst.
Utöver det tycker jag inte om att man anropar objekt två gånger, eftersom det kan innebära att det vid nästa anrop är null även om det första gången inte var det.
Snyggare och tydligare tycker jag är att skriva.
Vehichle vechicle = Session["VehicleUsed"];
if (vehicle == null)
{
vechicle = Vehicle.NotSet;
}
spangoMedlem sedan juni 20008 205 inlägg Chansen finns att du kommer vilja ha nåt mer än bara enums som sessionsdata, så gör en klass för det du vill ha i sessionen:
[Serializable]
class SessionData
{
public Vehicle SelectedVehicle { get; set; }
private SessionData(){ SelectedVehicle = Vehicle.NotSet; }
public static SessionData GetInstance(HttpSessionState session)
{
const string SessionKey = "SessionData";
var data = (SessionData)session[SessionKey];
if (data == null) session.Add(SessionKey, data = new SessionData());
return data;
}
}
// Användning:
var sd = SessionData.GetInstance(Session);
if (sd.SelectedVehicle != Vehicle.NotSet)
{
// gör nåt med fordonstypen
}
Med det här behöver du bara göra en enda slagning för att komma åt samtliga värden, och den här strategin kommer faktiskt resultera i att man i slutänden skapar färre objekt - färre nycklar i sessionsobjektet, och färre boxade värdetyper. Med andra ord är det både snabbare och läsbarare - finns inga ursäkter att låta bli :)
red. Haha, där fick jag på nöten. Kör man sessionshanteringen i out-of-process mode kommer det här bli långsammare pga att SessionData-objektet serialiseras fram och tillbaka. (Dock torde det fortfarande vara snabbare i inproc mode.)
http://www.eggheadcafe.com/articles/20021016.asp
http://blogs.msdn.com/tims/archive/2003/11/21/57453.aspx
Pwnt. Dock kan man förstås göra om sin klass så att den bara stoppar in värdetyper i sessionsobjektet, men det är en annan historia.