Pokračuji v odhalování dalších “skrytých” vlastností jazyka. Předchozí díl najdete zde.
String = IEnumerable<char>
Každý ví, že text je sekvence znaků, ale vždy se najde někdo, koho překvapí, že .NET to ví také. V souvislosti s následující ukázkou si také dovolím upozornit na některé užitečné metody typu Char, o kterých se také moc neví. Kombinace těchto znalostí může posloužit například i v pár případech, kdy by Vás napadlo použít regulární výrazy.
var text = "Just a string Literal";
var caps = text.Where(c => char.IsUpper(c)); // posbírá všechna velká písmena z textu
Mezi další užitečné metody patří třeba IsLetter() nebo IsNumber(). Kompletní seznam najdete na MSDN.
Názvy properties anonymního typu
Při vytváření anonymního typu nemusíte nutně specifikovat jména properties. Kompilátor si je může definovat sám v tomto případě.
var name = "Jane";
var surname = "Doe";
var o = new { name, surname };
Console.WriteLine("{0} {1}", o.name, o.surname);
Zde můžeme přimhouřit oko nad konvencemi, které diktují názvy properties začínající velkým písmenkem.
testování internal členů
Potřebujete napsat unit test pro nějaký internal kód a nechcete testy cpát přímo do projektu? Nemusíte.
// in Sandbox.B assembly
using System;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Sandbox.A")]
namespace Sandbox.B
{
internal class Test
{
internal static void DoSomething()
{
Console.WriteLine("Greetings from an internal class.");
}
}
}
// in Sandbox.A assembly
namespace Sandbox.A
{
class Program
{
public static void Main()
{
Sandbox.B.Test.DoSomething();
}
}
}
Atribut InternalsVisibleTo lze specifikovat buď na začátku souboru se zdrojovým kódem, a nebo v souboru AssemblyInfo. Já doporučuji druhý z uvedených, protože k tomu je ten soubor určen. Jinak je ale jedno, kde tento atribut uvedete, protože je aplikován na úrovni celé assembly. Navíc bych doporučil toto nastavení vypnout pro release jako v následující ukázce.
#if(DEBUG)
[assembly:InternalsVisibleTo("SomeAssembly")]
#endif
Upozornění: pokud máte některé typy private a rádi byste je otestovaly, rozhodně není vhodné je povyšovat na internal jen kvůli testům. Buď danou komponentu otestujte v rámci nějaké jiné, a nebo znovu zvažte vhodnost použitých modifikátorů přístupnosti.
Metoda List.ForEach
Ne, nepříšlo to s LINQ v rámci extension metod pro IEnumerable<T>, jak si původně mnoho lidí myslelo. Metoda List<T>.ForEach() už je tu od samého začátku (přesněji od .NET 2.0, kdy se přidal generický list), takže implementace rozhraní IEnumerable<T> na její používání nestačí, ale je nutné použít přímo List<T>.
Ptáte se, proč tato metoda nemá svoje zastoupení i v LINQ? Odpověď je snadná. Je navržen podle funkcionálního paradigma, které si zakládá na neměnnosti (immutability) a proto LINQ metody nemají žádné postranní efekty. Jsou používány pouze na formování dotazů.
var numbers = Enumerable.Range(1, 100).ToList();
numbers.ForEach(n => Console.WriteLine(n * n));
Na jejím používání osobně moc výhod nevidím. Kromě toho, že zápis může být kratší, je to méně zvyklý zápis, pro spoustu lidí hůře čitelný a navíc přijímá pouze jediný parametr typu Action<T>.
Podmíněné formátování čísel
Console.WriteLine("{0:kladne;zaporne;nic}", 123); // kladne
Console.WriteLine("{0:kladne;zaporne;nic}", -123); // zaporne
Console.WriteLine("{0:kladne;zaporne;nic}", 0); // nic
Toto formátování lze používat i v string.Format(). Kompletní seznam formátů čísel a pravidla ohledně formátování jsou dostupná na MSDN.