Paslėptos C # funkcijos?

Tai įvyko man po to, kai iš šio klausimo sužinojau:

 where T : struct 

Mes, C # kūrėjai, žinome C # pagrindus. Aš turiu omenyje deklaracijas, konvencijas, ciklus, operatorius ir kt.

Kai kurie iš mūsų net įsisavino tokius dalykus kaip Generics , anoniminiai tipai , lambdas , LINQ , ...

Bet kas yra labiausiai paslėptos savybės ar gudrybės C #, kad net C # gerbėjai, narkomanai, ekspertai vargu ar žino?

Čia pateikiamos galimybės:


Raktiniai žodžiai

Atributai

Sintaksė

Kalbos funkcijos

„Visual Studio“ funkcijos

Struktūra

Metodai ir savybės

Patarimai ir gudrybės

  • Geras būdas renginių tvarkytojams Andreas HR Nilsson
  • Palyginimas su didžiosiomis raidėmis john
  • Prieiga prie anoniminių tipų neatsižvelgiant į dp
  • Greitas būdas laisvai kurti kolekcijos savybes Will
  • „JavaScript“ tipo anoniminės „ roosteronacid “ funkcijos

Kita

1476
12 авг. Serhat Ozgel nustatė 12 rug . 2008-08-12 19:32 '08 ne 7:32 2008-08-12 19:32
@ 296 atsakymai

Tai nėra C # per se, bet nematau, kas iš tikrųjų naudoja System.IO.Path.Combine() , tiek, kiek jie turėtų. Tiesą sakant, visa kelio klasė yra tikrai naudinga, bet niekas jo nenaudoja!

Tikiu, kad kiekviena gamybos programa turi šį kodą, nors ji neturėtų:

 string path = dir + "\\" + fileName; 
752
13 авг. atsakymas duotas ageektrapped Aug 13 2008-08-13 04:53 '08 at 4:53 am 2008-08-13 04:53

lambdas ir tipo inferrencija yra nepakankamai įvertintos. „Lambdas“ gali turėti kelis pranešimus , ir jie automatiškai dvigubinami kaip suderinamasis delegato objektas (tik įsitikinkite, kad parašo atitikmenys), kaip:

 Console.CancelKeyPress += (sender, e) => { Console.WriteLine("CTRL+C detected!\n"); e.Cancel = true; }; 

Atkreipkite dėmesį, kad neturiu new CancellationEventHandler ir neturėčiau nurodyti sender ir e Tipų, jie yra kilę iš įvykio. Štai kodėl mažiau sudėtinga įrašyti visą delegate (blah blah) , kuriame taip pat reikia nurodyti parametrų tipus.

„Lambdas“ nereikia nieko grąžinti , o tipo išvados šiame kontekste yra labai stiprios.

Ir btw, jūs visada galite grąžinti „ Lambdas“, kuri „Lambdas“ atlieka funkcinį programavimą. Pavyzdžiui, čia yra lambda, kuri sukuria lambda, kuri tvarko mygtuką.

 Func<int, int, EventHandler> makeHandler = (dx, dy) => (sender, e) => { var btn = (Button) sender; btn.Top += dy; btn.Left += dx; }; btnUp.Click += makeHandler(0, -1); btnDown.Click += makeHandler(0, 1); btnLeft.Click += makeHandler(-1, 0); btnRight.Click += makeHandler(1, 0); 

Atkreipkite dėmesį į grandinę: (dx, dy) => (sender, e) =>

Dabar, kodėl aš džiaugiuosi, kad aš paėmiau funkcinę programavimo klasę: -)

Be nuorodų į C, manau, kad tai dar vienas esminis dalykas, kurį turėtumėte išmokti: -)

585
26 авг. atsakymas duotas chakritui 26 rug . 2008-08-26 21:34 '08 at 9:34 pm 2008-08-26 21:34

Nuo „ Rick Strall“ :

Ar galite susieti? operatorius, todėl galite atlikti nulinį palyginimą.

 string result = value1 ?? value2 ?? value3 ?? String.Empty; 
528
19 авг. atsakymas pateikiamas jfs 19 rug. 2008-08-19 08:43 '08, 08:43, 2008-08-19 08:43

Pseudonimai:

 using ASimpleName = Dictionary<string, Dictionary<string, List<string>>>; 

Tai leidžia naudoti ASimpleName o ne Dictionary<string, Dictionary<string, List<string>>> .

Naudokite, kai daugelyje vietų naudojate tą patį didelį, sudėtingą dalyką.

455
16 сент. Atsakymą pateikė BlackTigerX 16 Sep. 2008-09-16 19:53 '08, 19:53, 2008-09-16 19:53

Nuo CLR iki C # :

Normalizuojant eilutes, labai rekomenduojama naudoti ToUpperInvariant vietoj ToLowerInvariant, nes „ Microsoft“ optimizavo kodą, kad atliktų palyginimą didžiosiomis raidėmis .

Prisimenu, kol mano kolega prieš palygindamas visada pakeitė eilutes. Visada norėjau sužinoti, kodėl jis tai daro, nes jaučiuosi labiau „natūralus“, kad pirmiausia paverčiau mažosiomis raidėmis. Perskaitęs knygą, žinau, kodėl.

438
15 авг. atsakymas pateikiamas jfs 15 rug. 2008-08-15 14:06 '08 at 14:06 2008-08-15 14:06

Mano mėgstamiausia gudrybė yra „null coalesce“ operatorius ir skliausteliai, kad automatiškai sukurtų man atvejus.

 private IList<Foo> _foo; public IList<Foo> ListOfFoo { get { return _foo ?? (_foo = new List<Foo>()); } } 
409
12 сент. Atsakymas duotas Will 12 Sep 2008-09-12 16:25 '08 4:25 pm 2008-09-12 16:25

Venkite tikrinti, ar nėra null įvykių tvarkytojų.

Įtraukus tuščią delegatą į įvykius deklaracijoje, didžiausią būtinybę visada patikrinti įvykį prieš nulį, kol skambutis yra nuostabus. Pavyzdys:

 public delegate void MyClickHandler(object sender, string myValue); public event MyClickHandler Click = delegate {}; // add empty delegate! 

Leiskite tai padaryti

 public void DoSomething() { Click(this, "foo"); } 

Vietoj to

 public void DoSomething() { // Unnecessary! MyClickHandler click = Click; if (click != null) // Unnecessary! { click(this, "foo"); } } 

Taip pat žiūrėkite diskusiją ir šį įrašą „ Eric Lippert“ dienoraštyje (ir galimų trūkumų).

314
13 авг. atsakymas duotas ir 13 d. 2008-08-13 00:57 '08 at 0:57 2008-08-13 00:57

Visa kita plius

1) netiesioginiai generiniai vaistai (kodėl tik metodais, o ne klasėmis)?

 void GenericMethod<T>( T input ) { ... } //Infer type, so GenericMethod<int>(23); //You don't need the <>. GenericMethod(23); //Is enough. 

2) paprastas lambda su vienu parametru:

 x => x.ToString() //simplify so many calls 

3) anoniminiai tipai ir iniciatoriai:

 //Duck-typed: works with any .Add method. var colours = new Dictionary<string, string> { { "red", "#ff0000" }, { "green", "#00ff00" }, { "blue", "#0000ff" } }; int[] arrayOfInt = { 1, 2, 3, 4, 5 }; 

Kita:

4) Automatinės savybės gali būti skirtingos:

 public int MyId { get; private set; } 

Dėkojame, kad priminėte man:

5) Pseudonimų pavadinimai (ne tai, kad jums tikriausiai reikia šio ypatingo skirtumo):

 using web = System.Web.UI.WebControls; using win = System.Windows.Forms; web::Control aWebControl = new web::Control(); win::Control aFormControl = new win::Control(); 
305
12 авг. Keith pateikė atsakymą rugpjūčio 12 d. 2008-08-12 21:23 '08, 21:23, 2008-08-12 21:23

Aš nežinojau „kaip“ raktinio žodžio ilgą laiką.

 MyClass myObject = (MyClass) obj; 

prieš

 MyClass myObject = obj as MyClass; 

Antrasis nulinis, jei obj yra ne „MyClass“, o ne išskiria klasės išimtį.

286
12 авг. Mike Stone atsakymas 12 rug. 2008-08-12 19:42 '08 at 7:42 pm 2008-08-12 19:42

Du dalykai, kurie man patinka, yra automatinės savybės, todėl galite dar labiau išplėsti kodą:

 private string _name; public string Name { get { return _name; } set { _name = value; } } 

tampa

 public string Name { get; set;} 

Objekto iniciatoriai:

 Employee emp = new Employee(); emp.Name = "John Smith"; emp.StartDate = DateTime.Now(); 

tampa

 Employee emp = new Employee {Name="John Smith", StartDate=DateTime.Now()} 
262
13 авг. atsakymas pateikiamas lomaxx 13 rug . 2008-08-13 10:39 '08 at 10:39 2008-08-13 10:39

Numatytasis numatytasis raktinis žodis:

 T t = default(T); 

rezultatas yra „null“, jei T yra atskaitos tipas, o 0, jei jis yra int, false, jei jis yra loginis, ir pan.

255
13 авг. Eric Minkes atsakymas rugpjūčio 13 d 2008-08-13 13:20 '08 at 13.20 val. 2008-08-13 13:20

Atributai apskritai, bet visų pirma DebuggerDisplay . Taupo jūsų metus.

226
12 авг. Atsakymas pateikiamas Stu 12 rug. 2008-08-12 19:59 '08 at 19:59 pm 2008-08-12 19:59

@ Komanda nurodo kompiliatoriui ignoruoti bet kokias evangelinio simbolio eilutes.

Aš tik norėjau tai paaiškinti ... jis nesako jam ignoruoti pabėgėlių simbolių, jis iš tiesų sako kompiliatoriui interpretuoti eilutę kaip pažodinį.

Jei turite

 string s = @"cat dog fish" 

ji iš tikrųjų spausdins kaip (atkreipkite dėmesį, kad ji apima ir vietas, naudojamas atkarpoms):

 cat dog fish 
221
13 авг. atsakymas pateikiamas lomaxx 13 rug . 2008-08-13 05:07 '08, 5:07 am. 2008-08-13 05:07

Manau, kad viena iš nepakankamai įvertintų ir mažiau žinomų C # funkcijų (.NET 3.5) yra „ Expression Trees“ , ypač kai ji derinama su „Generics“ ir „Lambdas“. Tai yra būdas sukurti API, kuri naudoja naujesnes bibliotekas, pvz., „NInject“ ir „Moq“.

Pavyzdžiui, tarkime, kad noriu užregistruoti metodą su API ir kad API turėtų gauti metodo pavadinimą

Atsižvelgiant į šią klasę:

 public class MyClass { public void SomeMethod() {  } } 

Jis dažnai buvo labai dažnas norėdami pamatyti, kad kūrėjai tai daro su eilutėmis ir tipais (arba kažkas kita yra pagrįsta stygomis):

 RegisterMethod(typeof(MyClass), "SomeMethod"); 

Na, ji sucks, nes trūksta stipraus spausdinimo. Ką daryti, jei pervardysiu „SomeMethod“? Dabar, 3.5 punkte, galiu tai padaryti labai įvestu būdu:

 RegisterMethod<MyClass>(cl => cl.SomeMethod()); 

Kurioje „RegisterMethod“ klasėje naudojama „ Expression<Action<T>> :

 void RegisterMethod<T>(Expression<Action<T>> action) where T : class { var expression = (action.Body as MethodCallExpression); if (expression != null) { // TODO: Register method Console.WriteLine(expression.Method.Name); } } 

Tai viena iš pagrindinių priežasčių, kodėl aš dabar myliu Lambda ir „Expression Village“.

220
10 сент. Atsakyti Jason Olson 10 rugsėjis 2008-09-10 00:52 '08, 12:52 am. 2008-09-10 00:52

Mano galvoje ateis „ derlius “. Kai kurie atributai, tokie kaip [DefaultValue ()], taip pat taikomi mano mėgstamiesiems.

Var raktinis žodis yra šiek tiek labiau žinomas, bet jūs taip pat galite jį naudoti .NET 2.0 programose (jei naudojate .NET 3.5 kompiliatorių ir nustatote jį į 2.0 kodą), atrodo, nėra labai gerai žinoma.

Redaguoti: kokos, ačiū, kad nurodėte? operatorius, kuris yra tikrai naudingas. Kadangi „Google“ yra šiek tiek sudėtinga (nes ji tiesiog ignoruojama), čia yra šio operatoriaus MSDN dokumentacijos puslapis: ?? Operatorius (nuoroda į C #)

209
12 авг. Michael Stum atsakymas rugpjūčio 12 d 2008-08-12 19:34 '08, 19:34, 2008-08-12 19:34

Paprastai pastebiu, kad dauguma C # kūrėjų nežino apie „nullable“ tipus. Iš esmės primityvūs, kurie gali turėti nulinę vertę.

 double? num1 = null; double num2 = num1 ?? -100; 

Nustatykite reikšmę nullable double, num1, null, tada nustatykite reguliarius dvigubus, num2, num1 arba -100, jei num1 buvo nulis.

http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx

Dar vienas dalykas apie „Nullable“ tipą:

 DateTime? tmp = new DateTime(); tmp = null; return tmp.ToString(); 

grąžina String.Empty. Jei norite gauti daugiau informacijos, patikrinkite šią nuorodą.

198
12 авг. Atsakymas duotas Brad Barker 12 rug . 2008-08-12 20:07 '08 at 8:07 pm 2008-08-12 20:07

Štai keletas įdomių paslėptų „C #“ funkcijų, kurios yra „C“ raktinių žodžių dokumentais:

 __makeref __reftype __refvalue __arglist 

Tai yra dokumentais nesusiję C # raktiniai žodžiai (net ir „Visual Studio“ juos atpažįsta!) Tai buvo pridėta siekiant efektyvesnio bokso / išpakavimo prieš generinius vaistus. Jie dirba kartu su „System.TypedReference“ struktūra.

Čia taip pat yra __arglist, kuris naudojamas kintamojo ilgio parametrų sąrašams.

Vienas dalykas, apie kurį žmonės mažai žino, yra „ System.WeakReference“ - tai labai naudinga klasė, kuri seka objektą, tačiau leidžia šiukšlių surinkėjui ją surinkti.

Naudingiausia „paslėpta“ funkcija būtų raktinių žodžių derlius. Tai tikrai nėra paslėpta, bet daugelis žmonių apie tai nežino. LINQ yra pastatytas ant šios; tai leidžia atlikti užklausas su vėlavimu, sukuriant valstybinę mašiną po gaubtu. Raymond Chen neseniai paskelbė vidines detales .

193
12 авг. Judah Himango atsakymas, pateiktas rugpjūčio 12 d 2008-08-12 21:50 '08 at 9:50 pm 2008-08-12 21:50

Sąsajos (bendrosios atminties tipas C ++) švariame, saugiame C #

Nesikreipiant į nesaugų režimą ir rodykles, galite turėti klasės narius, kurie dalijasi atminties vieta klasėje / struktūroje. Atsižvelgiant į šią klasę:

 [StructLayout(LayoutKind.Explicit)] public class A { [FieldOffset(0)] public byte One; [FieldOffset(1)] public byte Two; [FieldOffset(2)] public byte Three; [FieldOffset(3)] public byte Four; [FieldOffset(0)] public int Int32; } 

Bitų lauko reikšmes galite keisti manipuliuojant Int32 lauką ir atvirkščiai. Pavyzdžiui, ši programa:

  static void Main(string[] args) { A a = new A { Int32 = int.MaxValue }; Console.WriteLine(a.Int32); Console.WriteLine("{0:X} {1:X} {2:X} {3:X}", a.One, a.Two, a.Three, a.Four); a.Four = 0; a.Three = 0; Console.WriteLine(a.Int32); } 

Rodo:

 2147483647 FF FF FF 7F 65535 

tiesiog pridėkite naudodami „System.Runtime.InteropServices“;

185
23 сент. Atsakymas pateikiamas ZeroBugBounce rugsėjo 23 d 2008-09-23 23:39 '08 at 11:39 2008-09-23 23:39

Naudokite @ kintamiesiems pavadinimams, kurie yra raktiniai žodžiai.

 var @object = new object(); var @string = ""; var @if = IpsoFacto(); 
176
18 авг. Mark Cidade atsakymas 18 rug. 2008-08-18 04:45 '08, 4:45 val. 2008-08-18 04:45

Jei norite išeiti iš programos, neskambindami jokių galutinių blokų ar baigėjų, naudokite „ FailFast“ :

 Environment.FailFast() 
168
14 окт. Jan Bannister atsakymas spalio 14 d 2008-10-14 01:25 '08, 1:25 am. 2008-10-14 01:25

Anoniminių tipų grąžinimas iš metodo ir prieigos prie elementų be atspindžio.

 // Useful? probably not. private void foo() { var user = AnonCast(GetUserTuple(), new { Name = default(string), Badges = default(int) }); Console.WriteLine("Name: {0} Badges: {1}", user.Name, user.Badges); } object GetUserTuple() { return new { Name = "dp", Badges = 5 }; } // Using the magic of Type Inference... static T AnonCast<T>(object obj, T t) { return (T) obj; } 
153
17 авг. atsakymas duotas denis phillips rugpjūčio 17 d 2008-08-17 04:01 '08 at 4:01 am 2008-08-17 04:01

Čia naudinga naudoti įprastas išraiškas ir failų takus:

 "c:\\program files\\oldway" @"c:\program file\newway" 

@ nurodo kompiliatoriui ignoruoti bet kokias eilutėje esančias pabėgimo simbolius.

146
12 авг. Atsakymas pateikiamas Patrick 12 rug. 2008-08-12 21:38 '08 at 9:38 pm 2008-08-12 21:38

Priemaišos. Iš esmės, jei norite pridėti funkciją į kelias klases, bet negalite naudoti tos pačios bazinės klasės visiems, kiekvienai klasei reikia įdiegti sąsają (be dalyvių). Tada parašykite sąsajos išplėtimo metodą, t.

 public static DeepCopy(this IPrototype p) { ... } 

Žinoma, tam tikras aiškumas yra paaukotas. Bet tai veikia!

142
26 окт. Spalio 26 d. Dmitrijus Nesterukas atsakė . 2008-10-26 22:04 '08, 10:04 val. 2008-10-26 22:04

Nežinote, kodėl kas nors kada nors norėtų naudoti „Nullable <bool>“.: -)

Tiesa, klaidinga, „ FileNotFound“ ?

131
12 авг. Michael Stum atsakymas rugpjūčio 12 d 2008-08-12 21:53 '08 at 9:53 pm 2008-08-12 21:53

Tai nėra paslėpta tiek, kiek yra neteisinga.

Daug dėmesio skiriama algoritmams „žemėlapis“, „mažinimas“ ir „filtras“. Dauguma žmonių nesupranta, kad .NET 3.5 pridėjo visus tris šiuos algoritmus, tačiau jis suteikė jiems labai SQL-ish pavadinimus, remdamasis tuo, kad jie yra LINQ dalis.

"map" => Pasirinkite
Konvertuokite duomenis iš vienos formos į kitą

„sumažinti“ => suvestinius suvestinius dydžius viename rezultate

"filter" => Kur
Kriterijai pagrįsti filtrai

Gebėjimas naudoti LINQ, siekiant atlikti eilinį darbą su kolekcijomis, naudojamomis atlikti iteracijas ir konvencijas, gali būti neįtikėtinai vertingas. Verta žinoti, kaip visi LINQ išplėtimo metodai gali padėti padaryti jūsų kodą labiau kompaktišką ir patogesnį.

117
17 авг. Atsakymas pateikiamas Brad Wilson 17 rug . 2008-08-17 02:55 '08 at 2:55 am 2008-08-17 02:55
 Environment.NewLine 

sistemos nepriklausomoms stygoms.

115
01 сент. Atsakymas pateikiamas nimish 01 Sep. 2008-09-01 03:03 '08 at 3:03 2008-09-01 03:03

Jei bandote naudoti garbanotus petnešus String.Format išraiška ...

 int foo = 3; string bar = "blind mice"; String.Format("{{I am in brackets!}} {0} {1}", foo, bar); //Outputs "{I am in brackets!} 3 blind mice" 
111
19 авг. Atsakymas duotas Portmanui 19 rugpjūčio mėn. 2008-08-19 01:29 '08 1:29 am 2008-08-19 01:29
  • ? - sutelkti operatorių
  • naudojant ( pareiškimą / direktyvą ) yra puikus raktinis žodis, kuris gali būti naudojamas ne tik skambinti
  • tik skaityti - turėtumėte naudoti daugiau
  • netmodules - per blogai vizualinėje studijoje nėra palaikymo
104
12 авг. atsakymą pateikė kokos 12 rug . 2008-08-12 19:35 '08 at 7:35 pm 2008-08-12 19:35

@Ed, aš šiek tiek suvaržau apie tai kalbėdamas, nes tai šiek tiek daugiau nei „captiousness“. Tačiau norėčiau pabrėžti, kad jūsų pavyzdiniame kode:

 MyClass c; if (obj is MyClass) c = obj as MyClass 

Jei ketinate naudoti „yra“, kodėl žiūrėkite jį saugiai, naudodami „kaip“? Jei nustatėte, kad obj yra tikrai „MyClass“, standartinė pelkės paraiška:

 c = (MyClass)obj 

... niekada neveikite.

Taip pat galite tiesiog pasakyti:

 MyClass c = obj as MyClass; if(c != null) { ... } 

Aš nežinau pakankamai apie .NET informatorius, bet mano instinktai man sako, kad tai sumažins maksimalią iki dviejų tipų sumažinimo operacijas. Tai vargu ar gali sulaužyti apdorojimo banką; Asmeniškai manau, kad pastaroji forma atrodo švaresnė.

103
12 авг. atsakymą pateikė Dogmang 12 rug . 2008-08-12 21:03 '08, 21:03 2008-08-12 21:03

Galbūt tai nėra pažangi technika, bet visada matau, kas mane išprotėja:

 if (x == 1) { x = 2; } else { x = 3; } 

gali būti sutrumpintas:

 x = (x==1) ? 2 : 3; 
98
19 авг. Atsakyti JasonS rugpjūčio 19 d 2008-08-19 18:54 '08 at 18:54 2008-08-19 18:54

Kiti klausimai apie žymes arba Užduoti klausimą