C Sharp 3.0
Programmeringsspråket C# version 3.0 släpptes den 19 november 2007 som en del av .NET Framework 3.5 . Den innehåller nya funktioner inspirerade av funktionella programmeringsspråk som Haskell och ML , och drivs till stor del av introduktionen av LINQ-mönstret ( Language Integrated Query ) i Common Language Runtime. Det är för närvarande inte standardiserat av någon standardiseringsorganisation .
C# 3.0 funktioner
LINQ (språkintegrerad fråga)
LINQ är ett nytt Microsoft-specifikt utbyggbart frågespråk för allmänna ändamål för många typer av datakällor – inklusive vanliga objektsamlingar, XML-dokument, databaser, etc. – som är tätt integrerat med andra C#-språkfaciliteter. Syntaxen skiljer sig från, men lånar från SQL . Ett exempel:
int [] array = { 1 , 5 , 2 , 10 , 7 }; // Välj kvadrater av alla udda tal i arrayen sorterade i fallande ordning IEnumerable < int > query = från x i array där x % 2 == 1 ordningsföljd efter x fallande välj x * x ; // Resultat: 49, 25, 1
För att implementera LINQ lades ett stort antal nya metoder till i många samlingar via klassen System.Linq.Enumerable .
LINQ-uttryck översätts till att använda dessa funktioner före kompilering. Som ett alternativ, som ibland är mer kraftfullt eller direkt, kan dessa funktioner nås direkt. Om du gör det använder du mer lambdafunktioner, som diskuteras nedan. Följande är funktionellt identisk med exemplet ovan.
IEnumerable < int > query = array . Där ( x => x % 2 == 1 ) . OrderByDescending ( x => x ) . Välj ( x => x * x ); // Resultat: 49, 25, 1 med 'array' som definierats i föregående exempel
Objektinitierare
Kund c = ny kund (); c . Namn = "John" ;
kan skrivas
Kund c = ny kund { Namn = "John" };
Samlingsinitierare
MyList list = ny MyList (); lista . Lägg till ( 1 ); lista . Lägg till ( 2 );
kan skrivas som
MyList list = new MyList { 1 , 2 };
förutsatt att MyList
implementerar System.Collections.IEnumerable
och har en offentlig Add-
metod.
Lokal variabel typ slutledning
Lokal variabel typ slutledning :
var x = new Dictionary < string , List < float >>();
är utbytbar med
Dictionary < string , List < float >> x = new Dictionary < string , List < float >>();
Denna funktion är inte bara ett bekvämt syntaktisk socker för kortare lokala variabeldeklarationer, utan det krävs också för deklaration av variabler av anonyma typer. Det kontextuella nyckelordet "var" kan dock endast förekomma i en lokal variabeldeklaration.
Anonyma typer
Anonyma typer ger ett bekvämt sätt att kapsla in en uppsättning skrivskyddade egenskaper i ett enda objekt utan att först behöva definiera en typ. Typnamnet genereras av kompilatorn och är inte tillgängligt på källkodsnivå. Typen av egenskaper härleds av kompilatorn.
var x = new { FirstName = "John" , Efternamn = "Doe" };
Anonyma typer är referenstyper som härrör direkt från objekt. Kompilatorn ger dem ett namn även om din applikation inte kan komma åt det. Ur perspektivet av den vanliga språkkörningen skiljer sig en anonym typ inte från någon annan referenstyp, förutom att den inte kan castas till någon typ förutom objekt.
Om två eller flera anonyma typer har samma antal och typ av egenskaper i samma ordning, behandlar kompilatorn dem som samma typ och de delar samma kompilatorgenererade typinformation.
Lambda uttryck
Lambda- uttryck ger ett kortfattat sätt att skriva förstklassiga anonyma funktionsvärden. Jämför följande C# 2.0-kodavsnitt:
listOfFoo . Där ( delegat ( Foo x ) { return x . Storlek > 10 ; });
med denna C# 3.0-motsvarighet:
listOfFoo . Där ( x => x . Storlek > 10 );
I exemplen ovan är lambda-uttryck bara förkortad syntax för anonyma delegater med typinferens för parametrar och returtyp. Men beroende på sammanhanget de används i, kan en C#-kompilator också omvandla lambdas till AST :er som sedan kan bearbetas under körning. I exemplet ovan, om listOfFoo
inte är en vanlig samling i minnet, utan ett omslag runt en databastabell, kan den använda den här tekniken för att översätta kroppen av lambda till motsvarande SQL-uttryck för optimerad exekvering. Hur som helst, själva lambda-uttrycket ser exakt likadant ut i koden, så sättet som det används under körning är transparent för klienten.
Uttrycksträd
Uttryck, som x <= y
, a = b + c
, eller till och med lambda-funktioner och andra komplexa former kan skapas dynamiskt med hjälp av uttrycksträd . Mycket av funktionaliteten tillhandahålls av statiska metoder i klassen System.Linq.Expressions.Expression
. Det finns också olika nya klasser i det namnutrymmet som representerar uttrycken och partiella uttryck som skapas av dessa metoder som mjukvaruobjekt. Dessa inkluderar BinaryExpression
, som kan representera x <= y
; LambdaExpression
och många andra. I kombination med aspekter av reflektions -API:t kan detta vara ett mycket kraftfullt verktyg, om än lite utmanande att skriva och felsöka.
Automatiska egenskaper
Kompilatorn genererar en privat instansvariabel och lämplig accessor och mutator given kod som:
offentlig sträng Namn { get ; privat set ; }
Förlängningsmetoder
Utvecklare kan använda förlängningsmetoder för att lägga till nya metoder till det offentliga kontraktet av en befintlig CLR-typ, utan att behöva underklassa den eller kompilera om den ursprungliga typen. I verkligheten är förlängningsmetoder en form av syntaktisk socker som ger illusionen av att lägga till nya metoder till den befintliga klassen utanför dess definition. Illusionen uppnås med definitionen av en statisk metod som är anropbar som om den vore en instansmetod, där mottagaren av anropet (dvs instansen) är bunden till metodens första parameter, dekorerad med nyckelordet detta
.
Kraven för en förlängningsmetod är följande:
- En förlängningsmetod måste definieras i en statisk klass.
- En förlängningsmetod måste definieras som en statisk metod.
- En extensionsmetods första parameter måste ha följande form, där typ är namnet på typen som ska utökas:
denna typ parameterName
- En förlängningsmetod kan valfritt definiera andra parametrar för att följa
denna
parameter.
Den här exempelklassen demonstrerar definitionen och användningen av en Left
extension-metod för strängar:
0
public static class StringExtensions { public static string Left ( denna sträng s , int n ) { return s . Delsträng ( , n ); } } string s = "foo bar" ; s . Vänster ( 3 ); // samma som StringExtensions.Left(s, 3), som returnerar "foo";
Partiella metoder
Partiella metoder tillåter kodgeneratorer att generera metoddeklarationer som förlängningspunkter som bara ingår i kompileringen om någon faktiskt implementerar dem i en annan del av en partiell klass.