W prostym przypadku, w którym jest to prosta pojedyncza konkatenacja, uważam, że nie jest to warte złożoności string.Format(i nie testowałem, ale podejrzewam, że w prostym przypadku, takim jak ten, string.Format może być nieco wolniejsze, co z parsowaniem ciągu formatu i wszystkie). Podobnie jak Jon Skeet, wolę nie wywoływać jawnie .ToString(), ponieważ zostanie to zrobione niejawnie przez string.Concat(string, object)przeciążenie i myślę, że kod jest bardziej przejrzysty i łatwiejszy do odczytania bez niego.
Ale dla więcej niż kilku konkatenacji (ile jest subiektywnych), zdecydowanie wolę string.Format. W pewnym momencie myślę, że zarówno czytelność, jak i wydajność niepotrzebnie cierpią z powodu konkatenacji.
Jeśli w ciągu formatu jest wiele parametrów (ponownie „wiele” jest subiektywne), zwykle wolę dołączać skomentowane indeksy do zastępowanych argumentów, aby nie stracić orientacji, która wartość trafia do którego parametru. Wymyślony przykład:
Console.WriteLine(
"Dear {0} {1},\n\n" +
"Our records indicate that your {2}, \"{3}\", is due for {4} {5} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary",
/*0*/client.Title,
/*1*/client.LastName,
/*2*/client.Pet.Animal,
/*3*/client.Pet.Name,
/*4*/client.Pet.Gender == Gender.Male ? "his" : "her",
/*5*/client.Pet.Schedule[0]
);
Aktualizacja
Wydaje mi się, że podany przeze mnie przykład jest nieco zagmatwany, ponieważ wygląda na to, że użyłem zarówno konkatenacji, jak i string.Formattutaj. I tak, logicznie i leksykalnie, właśnie to zrobiłem. Ale wszystkie konkatenacje zostaną zoptymalizowane przez kompilator 1 , ponieważ wszystkie są literałami łańcuchowymi. Więc w czasie wykonywania będzie jeden ciąg. Więc chyba powinienem powiedzieć, że wolę unikać wielu konkatenacji w czasie wykonywania .
Oczywiście większość tego tematu jest teraz nieaktualna, chyba że nadal utkniesz w C # 5 lub starszym. Teraz mamy interpolowane ciągi znaków , które pod względem czytelności są o wiele lepsze niż string.Formatw prawie wszystkich przypadkach. W dzisiejszych czasach, chyba że po prostu konkatenuję wartość bezpośrednio na początku lub na końcu literału ciągu, prawie zawsze używam interpolacji ciągów. Dzisiaj napisałbym mój wcześniejszy przykład w ten sposób:
Console.WriteLine(
$"Dear {client.Title} {client.LastName},\n\n" +
$"Our records indicate that your {client.Pet.Animal}, \"{client.Pet.Name}\", " +
$"is due for {(client.Pet.Gender == Gender.Male ? "his" : "her")} " +
$"{client.Pet.Schedule[0]} shots.\n" +
"Please call our office at 1-900-382-5633 to make an appointment.\n\n" +
"Thank you,\n" +
"Eastern Veterinary"
);
W ten sposób tracisz konkatenację w czasie kompilacji. Każdy interpolowany ciąg jest przekształcany w wywołanie string.Formatprzez kompilator, a ich wyniki są łączone w czasie wykonywania. Oznacza to, że jest to poświęcenie wydajności w czasie wykonywania na rzecz czytelności. W większości przypadków jest to opłacalne poświęcenie, ponieważ kara za bieganie jest znikoma. Jednak w przypadku kodu krytycznego dla wydajności może być konieczne profilowanie różnych rozwiązań.
1
Możesz to zobaczyć w specyfikacji C # :
... następujące konstrukcje są dozwolone w wyrażeniach stałych:
...
- Predefiniowany operator binarny + ...
Możesz to również zweryfikować za pomocą małego kodu:
const string s =
"This compiles successfully, " +
"and you can see that it will " +
"all be one string (named `s`) " +
"at run time";