Długie linie interpolacji ciągów w C # 6

138

Zauważyłem, że chociaż interpolacja ciągów jest naprawdę przyjemna, gdy jest stosowana do wywołań formatu ciągu w istniejącej bazie kodu, biorąc pod uwagę ogólnie preferowany limit kolumn, ciąg szybko staje się zbyt długi dla pojedynczej linii. Zwłaszcza, gdy interpolowane wyrażenia są złożone. Dzięki łańcuchowi formatującemu masz listę zmiennych, które możesz podzielić na wiele wierszy.

var str = string.Format("some text {0} more text {1}",
    obj1.property,
    obj2.property);

Czy ktoś ma jakieś preferowane sposoby przełamania tych linii?

Przypuszczam, że mógłbyś zrobić coś takiego:

var str = $"some text { obj1.property }" +
  " more text { obj2.property };
Jeremiah Gowdy
źródło
1
Z mojego doświadczenia wynika, że ​​lepiej unikać interpolacji złożonych wyrażeń. W takim przypadku raczej wyodrębnij zmienną. Jeśli to zrobisz i zerwiesz tam, gdzie masz znaki nowej linii w łańcuchach, zwykle będzie to dobrze pasować.
markijbema
2
Jestem zdezorientowany tym pytaniem. Chcę tylko multilinii, $""która działa jak@""
Colonel Panic
2
Pułkowniku Panic, pytanie dotyczy tego, jak rozdzielić długie wiersze interpolacji, aby nie naruszać wymagań dotyczących szerokości kolumn, bez wprowadzania znaków wysuwu do samego ciągu znaków. $ @ "" jest świetne, ale wszelkie wprowadzane do niego znaki nowej linii będą w literale ciągu.
Jeremiah Gowdy
4
Niebezpieczeństwo: $"some text { obj1.property }" + " more text { obj2.property }";nie robi tego, co myślisz, że robi. Tylko pierwsza połowa tego wyrażenia jest ciągiem interpolowanym; jest następnie łączony z nieinterpolowanym literałem ciągu" more text { obj2.property }"
bacar
1
Aby wesprzeć \ t \ r \ nw $ @, zobacz pytanie stackoverflow.com/questions/51991713/ ...
M.Hassan,

Odpowiedzi:

203

Państwo może przełamać linię do wielu linii, ale nie powiedziałbym, z ładnym wyglądem składniowe więcej.

Musisz użyć $@składni, aby użyć interpolowanego ciągu dosłownego i możesz umieścić znaki nowej linii wewnątrz {...}parametrów, na przykład:

string s = $@"This is all {
    10
    } going to be one long {
    DateTime.Now
    } line.";

Powyższy ciąg nie będzie zawierał żadnych nowych linii i faktycznie będzie miał następującą zawartość:

To wszystko 10 będzie jedną długą linią 01.08.2015 23.49.47.

(uwaga, format norweski)

Powiedziawszy to, nie przestałbym używać string.Format. Moim zdaniem niektóre z tych wyrażeń interpolacji ciągów wyglądają naprawdę dobrze, ale bardziej złożone stają się bardzo trudne do odczytania. Biorąc pod uwagę, że jeśli nie użyjesz FormattableString, kod i tak zostanie skompilowany w wywołanie do String.Format, powiedziałbym, że kontynuuj tam, String.Formatgdzie ma to sens.

Lasse V. Karlsen
źródło
Solidna odpowiedź. Jestem pewien, że też FormattableStringsprowadza się do wezwania String.Format.
Alex Booker
8
Ta odpowiedź pomogła mi dowiedzieć się, jak zrobić dokładnie odwrotnie. Dzięki za $@""składnię!
Bobson
1
@AlexBooker To bardziej złożone. Nie możesz tego zrobić, FormattableString.Invarian($"Hello {name}" + \n "are you the owner of {pet}?");ponieważ łączy dwa interpolowane ciągi w jeden prosty ciąg.
ANeves uważa, że ​​SE jest złem
Nowe linie i tabulatory są uwzględniane w interpolowanych dosłownych ciągach znaków. Wprowadź następujące informacje w interaktywnym oknie C #, a wynikowy ciąg zostanie sformatowany :. > var name = "Simon"; var templateName = "How to interpolate a verbatim string"; var now = DateTime.UtcNow;. var output = $@"Hi {name}, This template is a demo of {templateName}. It was ran at {now.ToString("o")}"; > output. Wynik to"Hi Simon,\r\nThis template is a demo of How to interpolate a verbatim string.\r\n\r\nIt was ran at 2020-01-24T15:49:35.6678353Z"
Enzoaeneas
1
@Enzoaeneas Myślę, że przeceniłeś obsługę formatowania w komentarzach, ale rozumiem i zgadzam się z tym, co mówisz.
Lasse V. Karlsen
63

Możesz łączyć $i @razem, aby uzyskać interpolację ciągów i wieloliniowy literał ciągu:

var str = $@"some text { obj1.property }
     more text { obj2.property }";

Ale to da ci NewLinepostać pomiędzy, więc może nie być tym, czego chcesz.

MarcinJuraszek
źródło
3
Ale czy @ faktycznie nie umieszcza znaku końca wiersza w dosłownym?
Jeremiah Gowdy
5
To robi. Zaktualizowałem moją odpowiedź, aby wyraźnie to powiedzieć.
MarcinJuraszek
Nie tylko nowy wiersz, ale także początkowe zakładki nowego wiersza. Aby poprawnie przedstawić rzeczywisty format ciągu znaków podczas korzystania $@"z programu Visual Studio, każdy nowy wiersz należy rozpoczynać od lewej strony edytora tekstu.
GDS
Dzięki temu rozwiązaniu nie możesz używać np. \ R i \ n w ciągu znaków
Johan Franzén
24

Podczas gdy OP poprosił o coś innego, spodziewam się, że wiele osób czytających to pytanie chciałoby interpolacji wielowierszowej, $""która działa jak @"". Aby to zrobić, użyj$@""

$@"Height: {height}
Width: {width}
Background: {background}"
Colonel Panic
źródło
3
Nie chce nowych linii na wyjściu, tylko sam kod do zawijania w różnych wierszach
Martin Capodici
7
Wyjaśnił, że ta odpowiedź była przeznaczona dla publiczności, która przybywa, szukając sposobu wykonywania wielowierszowych łańcuchów przy użyciu składni interpolacji ciągów.
Brandon Bonds
2

To jest to:

var str = $"some text { obj1.property }" +
          $" more text { obj2.property }";

Zwróć uwagę na drugą $w$"..." + $"..."

CallMeLaNN
źródło
19
Zauważ, że spowoduje to dwa wywołania String.Format, a także utworzy trzy ciągi w pamięci (strona A, strona B i A + B)
Kevin Kalitowski
1
Czy to nie powstrzymałoby cię przed użyciem FormattableStringrzutowania na połączonym łańcuchu?
binki
4
W wielu dzisiejszych implementacjach, pracując na procesorze GHz z gigabajtami pamięci, dodatkowe wywołanie i dodatkowy ciąg nie spowodują problemów z wydajnością. Problemy z wydajnością będą spowodowane np. Użyciem algorytmu O (n2). Myślę, że to niesprawiedliwe, by głosować przeciw temu facetowi.
Johan Franzén
1

Jako przykład użyłem StringBuilder w ramach zastąpionego ToString ().

    // return employee data
    public override string ToString()
    {
        StringBuilder buffer = new StringBuilder();
        buffer.AppendLine($"Number: {EmployeeNumber}");
        buffer.AppendLine($"Name: {EmployeeName}");
        buffer.AppendLine($"Address: {PostalAddress}");
        buffer.AppendLine($"Phone: {PhoneNumber}");
        buffer.AppendLine($"Age: {EmployeeAge}");
        buffer.AppendLine($"Gender: {EmployeeGender}");
        buffer.AppendLine($"Status: {EmployeeStatus}");
        buffer.AppendLine($"Manager: {EmployeeManager}");
        buffer.AppendLine($"Start: {EmployeeStartDate.ToShortDateString()}");
        return buffer.ToString();
    }
Christopher Govender
źródło
to dlaczego nie buffer.AppendFormat("{0}Number: {1}", Environment.NewLine, EmployeeNumber);???
TS