C# 'Geheimpjes'

Door RobIII op maandag 16 februari 2009 17:45 - Reacties (26)
CategorieŽn: Development, Life as a developer, Views: 9.102

Ik ben inmiddels toch al heel wat jaartjes werkzaam als programmeur en ik hou dat, denk ik, zo lang vol omdat het zo afwisselend is. Als je van opdracht naar opdracht gaat wissel je feitelijk al van baan. Je moet jezelf dan weer compleet nieuwe materie eigen maken om het project Łberhaupt te kunnen bevatten. Ik heb aan zoveel uiteenlopende zaken gewerkt dat ik van de gekste dingen kennis heb :P

http://tweakers.net/ext/f/OHHEXzg4Yox0tqdRieGOooyw/full.jpgEn dan heb ik nog het geluk dat ik, als ware ik een 'tweebenige voetballer', naast mijn Windows ("Winforms") development me ook nog eens regelmatig kan uitleven op een web-project voor deze of gene. Van kleine componentjes als (ActiveX) custom controls tot complete facturerings-, track'n'trace- of informatiesystemen, van "veredelde visitekaartjes" op het web tot uit de kluiten gewassen webshops. Je kunt het zo gek niet bedenken.

Wat wel vaak, min-of-meer, een constante is is de taal en/of het platform waarin of waarop je werkt. Zo heb ik jaren gewerkt met VB6 en ("classic") ASP en zo nu en dan val ik er nog wel eens graag op terug voor het Quick'n'dirty werk. En door die jaren heen pik je toch heel wat handigheidjes op. En hoewel je vaak een voorkeur hebt voor een taal en/of platform, als programmeur zijnde ben je vaak toch ook nieuwsgierig waar anderen het over hebben. Zo kom je in aanraking met diverse talen en platformen en leer je waarderen wat het voordeel van elk is en kun je soms zelfs vanaf dat moment eindelijk eens mee-ranten met de rest als het over een nadeeltje gaat waar je voorheen niet over kon meepraten. Zo heb ik onlangs wat zaken met PHP moeten en heb ik nu een hogere dunk dan voorheen van het "Pretty Home Prutsers" taaltje zoals ik het liefkozend altijd noemde. Zie het niet als een aanval; ik geef juist aan dat ik er wijzer van ben geworden sinds mijn uitstapje. Maar ik heb nu ook betere kennis van de minpuntjes. En ik heb nou eenmaal mijn voorkeuren voor talen en platformen, net zoals jij dat waarschijnlijk hebt. De ťťn kiest de erwtensoep vooraf, de ander de carpaccio ( :9 ).

http://tweakers.net/ext/f/Q93WO6ueLlW2zTwil7TrulnR/full.jpgGoed, waar ik naar toe wilde maar van af dwaal is het volgende: ik denk dat het A-good-thing™ is om, als programmeur zijnde, zo nu en dan eens om je heen te kijken. Hoe meer kennis je van verschillende technologieŽn je hebt, hoe beter je kunt kiezen voor technologie X wanneer je weer eens aan een nieuw project begint. Een timmerman heeft ook niet alleen een hamer aan zijn riem hangen. En hoewel je soms beter bent met een hamer dan een zaag is het soms toch de juiste keuze om een zaag te gebruiken in plaats van je favo hamer. Een beetje programmeur heeft een flink arsenaal aan gereedschap in z'n gereedschapskist gestopt. Kijk eens bij de buren. Verdiep je eens in Linux als Windows developer; of andersom: verdiep je in Windows als je Linux adept bent. Verdiep je eens in Ruby als PHP-er zijnde. Verdiep je eens in Silverlight i.p.v. je zoveelste Flash creatie op te leveren. Speel eens met Python, Erlang of C++ naast je VB.Net werkzaamheden. Probeer eens Eclipse in plaats van Visual Studio. Sommige zaken staan haaks op elkaar; andere zaken vullen elkaar mooi aan en sommige zaken blijken achteraf minder de moeite waard dan je in eerste instantie dacht. Maar er is zů veel om eens te besnuffelen. Zo veel te leren. Zo veel te beleven. En verandering van spijs doet eten :Y)

http://tweakers.net/ext/f/N3MAT3nNDEto1lCIIzHh6fCb/full.jpgMaar... ook al ken je, denk je, je spreekwoordelijke hamer als je spreekwoordelijke broekzak, soms blijkt die vertrouwde hamer nog een kunstje te kunnen waarvan je nog niet wist. En die zaken kom je vaak wat onverwachter tegen; je loopt er spontaan tegen aan of je hebt ergens behoefte aan waarvan je in eerste instantie denkt dat het niet kan met je hamer maar blijkt, bij nader onderzoek, prima mogelijk. En nog beter dan je had gehoopt ook! En dat hou je dan natuurlijk niet voor jezelf maar deel je met je 'peers' zoals dat zo hip heet. Zo heb ik vandaag in de aanbieding wat geinige "Did you know" gevalletjes voor C#; mijn 'hamer' van afgelopen jaren. Misschien ken je ze al, misschien ontdek je wel iets nieuws hier. Who knows. Maar het is wel leuk om even te kijken of je nog iets kunt opsteken naast dit oeverloze geblaat, toch?

Here we go:

Tip 1: ?? Operator
The ?? operator returns the left-hand operand if it is not null, or else it returns the right operand.
Ofwel:

C#:
1
2
3
4
if (myobject == null)
    return _defaultobject;
else
    return myobject


Kan voortaan zo geschreven worden:

C#:
1
return myobject ?? _defaultobject;



Tip 2: Null event handler
Deze verdient misschien niet de schoonheidsprijs, maar scheelt je wel een boel code kloppen:

C#:
1
2
public delegate void MyClickHandler(object sender, string someValue);
public event MyClickHandler Click = delegate {}; // Lege delegate!


En dan kunnen we voortaan schrijven:

C#:
1
Click(this, "foo");


in plaats van:

C#:
1
2
3
4
if (Click != null) // Overbodig!
{
    Click(this, "foo");
}



Tip 3: literals
De meesten kennen wel de f-suffix om de compiler te vertellen dat een constante een float moet zijn. Maar ken je de volgende suffixes ook?

C#:
1
2
3
4
5
6
1.23m;  //Decimal
1.23f;  //Float
1.23d;  //Double
123u;   //UInt
123L;   //Long
123ul;  //ULong


De Long is geschreven met uppercase L; dit omdat VS heel netjes waarschuwt dat de lowercase l wel eens voor het getal 1 aangezien kan worden. En terecht! :)

Tip 4: Object en Collection Initializers
Wederom een tip die je code wat compacter maakt:

C#:
1
2
3
4
5
private class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}


Voorheen moest je dit doen:

C#:
1
2
3
Product MyProduct = new Product();
MyProduct.Name = "Teapot";
MyProduct.Price = 19.99m;


Met object initializers:

C#:
1
Product MyProduct = new Product { Name = "Teapot", Price = 19.99m };


Overigens; hier zie je meteen Auto-Implemented Properties in de Product class.

Tip 5: Het @ karakter
Ook geen schoonheidsprijs, maar toch: je kunt reserved words prefixen met het @ karakter:

C#:
1
2
3
string @string = "";
int @object = 4;
var @var = DoSomething();


Je ziet waarom dit geen schoonheidsprijs verdient; een reserved word gebruiken als variabelenaam is sowieso altijd een bad-idea™. Je kunt het @ karakter echter ook inzetten als verbatim string literal:

C#:
1
2
3
string root = "C:\\foo\\bar";
//Is hetzelfde als:
string root = @"C:\foo\bar";


Ook erg handig bij Regular Expressions :D

Een aantal kende ik al, maar gebruik(te) ik zelden tot nooit, een aantal waren nieuw voor me en de rest zijn misschien wel oude koeien voor je; Dan zijn er alweer wat nieuwe zaken op komst. En niet per se c# specifiek zijn er ook nog heel wat leuke .Net framework zaken waar je misschien nog niet van op de hoogte was maar die je leven oh-zo kunnen veraangenamen. De fervente stackoverflow.com lezers zal vast opgevallen zijn waar ik mijn inspiratie vandaan heb gehaald; en zo niet dan is het zťker even het doorbladeren waard. Het woord 'goudmijntje' is wat veel van het goede, maar ik kan niets beters verzinnen dan dat op het moment.

Nee; ik zal me niet snel vervelen. Volgende keer een stukje over slaaptekort :P

TwitterNuJIJeKudosFacebookFriendfeedGoogle BookmarksDiggdel.ici.ousTechnoratiSphinnMixxStumpleUponYahoo! BookmarksMaak je eigen RML op RobIII.nl!

Volgende: In het land der blinden... part 3 08-'09 In het land der blinden... part 3
Volgende: War of the Worlds 02-'09 War of the Worlds

Reacties


Door Tweakers user Sebazzz, maandag 16 februari 2009 20:34

Ja dat is inderdaad wel cool. Microsoft kan geen OS'en maken maar development tools en frameworks zijn ze hartstikke goed in! Tijd dat ze hun core business veranderen ;) C#.NET is een van de mooiste creaties :)

Door Tweakers user mOrPhie, maandag 16 februari 2009 20:35

Het @-karakter gebruik je ook als je class name een preserved keyword is. Zo genereerde mijn O/R-Mapper laatst "@event" voor een sql-tabel die "event" bleek te heten. Dus:


code:
1
2
3
4
5
6
7
8
9
10
11
12
public class event 
{
    [...]
}

public class eventBL
{
    public @event Event
    {
        get; set;
    }
}



Ik weet het, je hebt liever class-names met een hoofdletter (ik ook, daarom ging ik hier mee akkoord), maar even om het punt duidelijk te maken dus. ;)

Door Tweakers user LuckY, maandag 16 februari 2009 20:56

Het nadeel is het combineren van de pagina's
AFAIK (met mijn uber uber basic programeer skillz) kan je niet een enkele php elementen gebruiken in een ASP pagina. of je moet met Iframes (is dat de juiste benaming :X ) gaan werken.
Dus er is dan volgens mij nooit Globaal gezien een ideale programmeer taal,omdat je ze niet kan combineren.
Of je komt dan ben je useabilty in de knoei; Scherm 1 in php, scherm 2 in ASP.
correct me if i am wrong :)

Door Roflnator, maandag 16 februari 2009 21:01

Nog een ander ´geheimpje' of nouja, het is meer een feature die in .NET 3.0 gekomen is (LINQ)

public Person GetPersonByName(string name)
{
foreach(Person p in persons)
{
if(p != null)
{
return p;
}
}
return null;
}

Dit kan ook in 1 regel:
Person person = persons.FirstOrDefault(p=>p.name == "Roflnator");

:)

Door Tweakers user Forcepoint, maandag 16 februari 2009 21:04

Tip 1 en 2 gaan me een hoop schrijfsel schelen, bedankt :)

@Roflnator, die is ook handig!

Door Tweakers user Snake, maandag 16 februari 2009 21:10

Bij die eventhandler: Als je zoiets hebt in je API kan je toch beter checken of die null is, want wat als de developer een uninitialized var toewijst? Krijg je toch nog een NullPointerException :)

Door Tweakers user vdevos, maandag 16 februari 2009 21:16

Mocht ik nou net een Class aan het maken zijn met meerdere properties waarbij sommige parameters niet in de constructur ingevuld hoefde te worden waardoor ik dus bij sommige properties inderdaad eerst moest kijken of deze null was ;)


C#:
1
public string loginDate { get { return _loginDate ?? null; } }


Door Tweakers user Snake, maandag 16 februari 2009 21:25

@vdevos:

jouw code is deze code:


C#:
1
2
3
4
if(_loginDate == null)
return null;
else
return _loginDate



Waarom niet gewoon
C#:
1
return _loginDate;

? :P

Door Tweakers user Vedett., maandag 16 februari 2009 21:28

Dat met die EventHandlers kan tegenwoordig ook op een leuke manier worden opgelost met extension methods.

public static class EventHandlerExtensions
{
public static void Raise(this EventHandler eventHandler, object sender, EventArgs eventArgs)
{
if (eventHandler.IsNotNull())
eventHandler(sender, eventArgs);
}
}


En dan kan je gewoon
MyEventHandler.Raise(this, eventArgs);
doen

Door Tweakers user RobIII, maandag 16 februari 2009 21:40

@Sebazz:
Microsoft kan geen OS'en maken maar development tools en frameworks zijn ze hartstikke goed in!
Gee whizz... :| :O Tegen de tijd dat jij een OS geschreven hebt dat eender welk OS van MS voorbijstreeft praten we verder ;)

@mOrPhie:
Het @-karakter gebruik je ook als je class name een preserved keyword is.
Dat zei ik toch ook? :P

@LuckyY:
Het nadeel is het combineren van de pagina's
AFAIK (met mijn uber uber basic programeer skillz) kan je niet een enkele php elementen gebruiken in een ASP pagina. of je moet met Iframes (is dat de juiste benaming :X ) gaan werken.
Euh... :? :X Je kunt in een iFrame zelfs een compleet andere site openen; heeft geen drol met de taal te maken. En php en asp kun je prima 'mixen'; althans: je kunt ze binnen dezelfde site prima gebruiken maar natuurlijk niet binnen 1 script.
Dus er is dan volgens mij nooit Globaal gezien een ideale programmeer taal,omdat je ze niet kan combineren.
Die zal er ook nooit zijn; maar ik snap nog steeds niet wat je bedoelt met combineren?
Of je komt dan ben je useabilty in de knoei; Scherm 1 in php, scherm 2 in ASP.
Wat heeft useability met php/asp te maken :?

@Roflnator: dat heet Lambda expressions en kan ook met anonymous methods opgelost worden; hoewel minder elegant om te zien IMHO :) en je foreach loop is onzinnig, maar dat was vast niet je bedoeling... ;)

[Reactie gewijzigd op maandag 16 februari 2009 22:15]


Door Tweakers user Flard, maandag 16 februari 2009 23:11

Ik weet niet of je toevallig Stack OVerflow kent, maar die hebben ook een 'topic' met daarin allemaal 'hidden features' van C#:

http://stackoverflow.com/questions/9033/hidden-features-of-c

Ook erg interessant, al zijn dit soort tips wel vaak voor ervaren developers. Beginnelingen hebben vaak de neiging deze features te misbruiken, waardoor het alleen maar slechter wordt.

Door Tweakers user RobIII, maandag 16 februari 2009 23:13

@Flard: Lees de laatste alinea nog eens ;)

Door Tweakers user Flard, maandag 16 februari 2009 23:27

Neej!

Gaat zich in een hoekje zitten schamen. Dat ik daar overheen heb gelezen.
Mijn meer dan welgemeende excuses :) :+

Door Tweakers user RobIII, maandag 16 februari 2009 23:28

:D Zo erg is 't ook weer niet :P

[Reactie gewijzigd op maandag 16 februari 2009 23:32]


Door Tweakers user mOrPhie, dinsdag 17 februari 2009 10:10

Dat zei ik toch ook? :P
Mjah, het is een flauw verschil :P, maar jij had het over variabelenamen, ik heb het over class-namen bij het initializeren van een object. :)

Dat zijn twee verschillende dingen, al lijkt het erg op elkaar in het gebruik ervan.

Door Tweakers user HawVer, dinsdag 17 februari 2009 11:20

Leuk om te lezen over c#.
Tip 1. is een goede tip. :) Hoe vaak je wel niet null reference excepties om je oren krijgt.

Verder een nadeel van de tips is dat je je bindt aan het .NET framework 3.0 of later. De reden dat het een nadeel is, is dat de runtime om en nabij 120 mb is. (bloatware?) en je zet een streep door mono. Genoemde punten zijn uiteraard niet altijd relevant. :P

Door Tweakers user RobIII, dinsdag 17 februari 2009 12:09

Ik werk zelf ook nog graag met het .Net 2.0 framework, maar veel zaken zitten wel al in C# 3.0 ook al is het dan het .Net 2.0 framework dat je gebruikt.

Door Pasz, dinsdag 17 februari 2009 13:29

Goed verhaal. Doet me denken aan het Golden Hammer anti-pattern.
Ik had ooit een collega die alles met BizTalk wilde oplossen. Echt alles ! Zelfs de simpelste dingetjes.

Je tips zijn erg leuk, maar pas op dat je code er niet minder leesbaar door wordt.
Soms is het niet erg om een uitgebreide if/then constructie op te zetten, ipv op 1 regel. Beter leesbaar en de compiler maakt er uiteindelijk vaak hetzelfde van.

Door Tweakers user PhoenixT, dinsdag 17 februari 2009 18:15

Wat is eigenlijk het nut van auto-implemented properties?
Je kunt toch net zo goed dit gebruiken:

code:
1
2
3
4
5
private class Product
{
    public string name;
    public decimal price;
}



Ik kan me alleen iets erbij voorstellen als je de data read-only wilt maken, dus dat je alleen "get;" in de property zet en niet "set;".

Door Tweakers user RobIII, dinsdag 17 februari 2009 18:21

Wat is eigenlijk het nut van auto-implemented properties?
Nou....

C#:
1
2
3
4
5
private class Product
{
    public string name { get; private set; }
    public decimal price;
}



Je kunt voor de get/set een access modifier opgeven.

[Reactie gewijzigd op dinsdag 17 februari 2009 19:13]


Door Tweakers user Sebazzz, dinsdag 17 februari 2009 21:30

En zelfs nog is het vaak een goed gebruik om publiek alleen maar properties en geen velden te tonen. Auto-props gebruik ik niet: ik doe het gewoon handmatig of laat het automatisch refactoren.

Door Tweakers user RobIII, dinsdag 17 februari 2009 21:42

En zelfs nog is het vaak een goed gebruik om publiek alleen maar properties en geen velden te tonen.
Wat is het verschil dan functioneel(!) gezien tussen:

C#:
1
2
3
4
public class ProductA
{
    public string name;
}

en:
C#:
1
2
3
4
5
6
7
8
public class ProductB
{
    private string _name;
    public string name {
        get { return _name; }
        set { _name = value; }
    }
}

en:
C#:
1
2
3
4
public class ProductC
{
    public string name { get; set; }
}



:?

Los van wat zaken als metadata, de publieke interface die ietwat verschilt etc. doen beide (A en B-of-C) namelijk precies hezelfde. Het is idd een goed gebruik om properties te gebruiken, maar dat is enkel omdat, mocht je later nog zeken in de getter/setter willen stoppen, je interface dan niet verandert. Leesvoer: hier :Y)
De belangrijkste zaken daarin:
• To the user of an object, a property appears to be a field, accessing the property requires the same syntax.
• Unlike fields, properties are not classified as variables. Therefore, you cannot pass a property as a ref (C# Reference) or out (C# Reference) parameter.
• Properties have many uses: they can validate data before allowing a change; they can transparently expose data on a class where that data is actually retrieved from some other source, such as a database; they can take an action when data is changed, such as raising an event, or changing the value of other fields.
My point being: "Het is goed gebruik" is slechts half-the-reason. Het wordt pas leuk als je ook weet (of aangeeft) waarom dat zo is ;)

Vaak wordt er overigens beweerd dat een field 'sneller' zou zijn omdat het een rechtreekse referentie naar de variabele zou zijn, dus zonder de overhead van een getter method. Echter:
when you are returning the private variable from the get accessor and optimizations are enabled, the call to the get accessor method is inlined by the compiler so there is no method-call overhead

[Reactie gewijzigd op dinsdag 17 februari 2009 21:55]


Door Tweakers user Exirion, woensdag 18 februari 2009 13:00

Sebazzz: je zegt dat Microsoft zo geweldig in de ontwikkeling van frameworks en tools is, maar het belangrijkste brein achter C# is iemand die ze bij Borland vandaan geplukt hebben. Gezien je leeftijd verwacht ik niet dat je Turbo Pascal/C++ enzo nog gekend hebt, maar in die tijd was Borland superieur aan Microsoft wat ontwikkeltools betreft.

Door Tweakers user roy-t, woensdag 18 februari 2009 13:47

@Exirion, sorry hoor maar gaat dit over. C# is een taal gebaseerd / die compileerd naar MSIL. Er is inderdaad 1 man die Object Pascal heeft ontworpen die mee heeft gewerkt aan C# (als development lead). Maar het hele .Net framework heeft deze man niets mee te maken gehad. (En al had hij het in zijn eentje ontworpen als werknemer van MS, dan heeft MS toch nogsteeds een erg goed framework?).

Het klopt inderdaad dat rond 1997 Borlands C++ superieur geacht werd aan die van MS, so what. We leven nu in 2009. MS heeft ontzettend goede ontwikkel tools, net als SUN heeft met java en Netbeans. Borland is 3x opgesplits en de IDE afdeling zit nu in een eigen bedrijf en heet nu CodeGear, maar is lang niet meer zo succesvol als de tijd toen het nog Delphi heete.

Maar goed @ RobIII.

Ik kan je het boek PRO C# 2008 and the .Net3.5 Platform aan raden, het is echt de C# bijbel. En er staan veel truukjes in, ook is het helemaal aangevuld met alle nieuwe dingen zoals lambda's. en het var keyword wat vooral handig is icm LINQ. (wat natuurlijk ook een eigen hoofdstuk heet.) Eigenlijk is C# nu in de 2008 Versie JAva duidelijk voorbij gestreefd (terwijl de 2005 en 2003 versies nog redelijk on-par waren met Java.) Ik ben wel erg benieuwd naar Java 7, maar C# is gewoon ontzettend veel cleaner.

En ja Visual Studio 2008 (Express) is in mijn ogen gewoon een van de beste IDE's ( Netbeans 6.5 volgt wel op de voet maar is iets trager met bijv 'intellisense'. ) Maar ik verkijk me natuurlijk ook niet op 1 taal en ben laatst is begonnen met PHP, en het heeft inderdaad wel iets. (hoewel sommige dingen echt vreselijk zijn!).

Door Tweakers user Omega007, vrijdag 20 februari 2009 22:07

Roflnator zal ongetwijfeld dit hebben bedoeld:

if(p != null && p.name == "Roflnator")

@roy-t
Wat ik trouwens wel fijn vind aan de intellisense van Netbeans is dat het met de variabelen van het type aankomt die je op dat moment daar kunt gebruiken, dus als je functie een String vraagt geeft het netjes een list met alle Strings die beschikbaar zijn. In plaats van Visual Studio die gewoon alles terug geeft wat het kon vinden.

Door Tweakers user Sebazzz, zaterdag 21 februari 2009 10:17

quote: Exterion
Gezien je leeftijd verwacht ik niet dat je Turbo Pascal/C++ enzo nog gekend hebt, maar in die tijd was Borland superieur aan Microsoft wat ontwikkeltools betreft.
Pascal niet, maar C++ wel met een Microsoft compiler.

Reageren is niet meer mogelijk