Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Jegyzet
Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.
A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.
A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.
Bajnoki probléma: https://github.com/dotnet/csharplang/issues/8647
Összefoglalás
Adjon meg egy új sztring literált, amely legalább három """ karakterből áll (maximum megkötés nélkül), amelyet opcionálisan egy new_lineés a sztring tartalma követ, majd ugyanannyi idézőjellel végződik, amennyivel a literál kezdődött. Például:
var xml = """
<element attr="content"/>
""";
Mivel a beágyazott tartalom maga is használni szeretné a """, a kezdő/záró elválasztók hosszabbak lehetnek, mint a következő:
var xml = """"
Ok to use """ here
"""";
Annak érdekében, hogy a szöveg könnyen olvasható legyen, és lehetővé tegye a fejlesztők által a kódban használt behúzást, ezek a sztringkonstansok természetesen eltávolítják az utolsó sorban megadott behúzást a végső literális érték létrehozásakor. Például egy ilyen formájú literál:
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
A következő tartalommal rendelkezik:
<element attr="content">
<body>
</body>
</element>
Ez lehetővé teszi a kód természetes megjelenését, miközben továbbra is a kívánt literálokat készíti, és elkerüli a futásidejű költségeket, ha ez speciális sztringmanipulálási rutinokat igényel.
Ha a behúzási viselkedés nem kívánatos, akkor annak letiltása is egyszerű:
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
Az egysoros űrlap is támogatott. Legalább három """ karakterrel kezdődik (de nincs maximális), a szöveg tartalma (amely nem tartalmazhat new_line karaktereket), majd ugyanannyi idézőjellel végződik, amennyivel a szöveg elkezdődött. Például:
var xml = """<summary><element attr="content"/></summary>""";
Az interpolált nyers karaktersorozatok is támogatottak. Ebben az esetben a karakterlánc az interpoláció elindításához szükséges kapcsos zárójelek számát adja meg (a literál elején lévő dollárjelek száma határozza meg). Bármely olyan kapcsos zárójelekből álló sorozatot, amelynél kevesebb kapcsos zárójel van, mint a meghatározott mennyiség, egyszerűen tartalomként kezelünk. Például:
var json = $$"""
{
"summary": "text",
"length" : {{value.Length}},
};
""";
Motiváció
A C#-nak nincs általános módja egyszerű sztringkonstansok létrehozására, amelyek hatékonyan tartalmazhatnak tetszőleges szöveget. Minden C# sztringkonstansformának szüksége van valamilyen menekülési formára, ha a tartalom valamilyen speciális karaktert használ (mindig ha elválasztó karaktert használ). Ez megakadályozza, hogy a literálok más nyelveket (például XML-, HTML- vagy JSON-literálokat) tartalmazzanak.
A konstansok C#-ban való kialakításának jelenlegi összes módszere mindig arra kényszeríti a felhasználót, hogy manuálisan lépjen ki a tartalomból. A szerkesztés ezen a ponton nagyon bosszantó lehet, mivel a menekülés nem kerülhető el, és minden alkalommal foglalkozni kell vele, amikor a tartalomban felmerül. Ez különösen fájdalmas a regexek esetében, különösen akkor, ha idézőjeleket vagy fordított perjeleket tartalmaznak. Még egy szószerinti (@"") sztring esetén is az idézőjeleket escape-elni kell, ami a C# és a regex összekeveredéséhez vezet.
{ és } hasonlóan frusztrálóak az interpolált ($"") karakterláncokban.
A probléma fő oka az, hogy minden sztringnek rögzített kezdő-/véghatárolása van. Mindaddig, amíg ez a helyzet, mindig rendelkeznie kell egy menekülési mechanizmussal, mivel a sztring tartalmának meg kell adnia az adott véghatárolót a tartalmaikban. Ez különösen problémás, mivel az elválasztó " számos nyelven rendkívül gyakori.
Ennek megoldása érdekében ez a javaslat lehetővé teszi a rugalmas kezdő- és véghatárolók számára, hogy mindig olyan módon legyenek létrehozva, amely nem ütközik a sztring tartalmával.
Célok
- Adjon meg egy mechanizmust, amely lehetővé teszi, hogy a felhasználó minden karakterlánc értéket biztosítson anélkül, hogy bármilyen escape-szekvenciát kellene használni. Mivel minden sztringnek escape-szekvenciák nélkül kell ábrázolhatónak lennie, a felhasználónak mindig olyan elválasztójeleket kell megadnia, amelyek garantáltan nem ütköznek semmilyen szöveges tartalommal.
- Azonos módon támogatja az interpolációkat. A fentieknek megfelelően, mivel minden sztringnek feloldás nélkül kell ábrázolhatónak lennie, mindig lehetővé kell tenni, hogy a felhasználó olyan
interpolationelválasztót adjon meg, amely garantáltan nem ütközik semmilyen szöveges tartalommal. Fontos, hogy a interpolációs elválasztó karaktereket ({és}) használó nyelvek első osztályúnak tűnjenek, és ne legyen nehézkes a használatuk. - A többsoros sztringkonstansoknak jól kell kinézniük a kódban, és nem szabad, hogy a fordítási egységen belüli sorkihúzás furcsának tűnjön. Fontos, hogy azok a literális értékek, amelyek maguk nem rendelkeznek behúzással, nem kell megjelenniük a fájl első oszlopában, mivel ez felbonthatja a kódfolyamot, és nem fog igazodni az azt körülvevő kód többi részéhez.
- Ennek a viselkedésnek könnyen felülírhatónak kell lennie, miközben a literálok egyértelműek és könnyen olvashatók maradnak.
- Minden olyan sztring, amely sem
new_line-t nem tartalmaz, sem idézőjel (") karakterrel nem kezdődik vagy végződik, egyetlen sorban jeleníthető meg szövegkonstansként.- A további összetettség mellett finomíthatjuk a következőt: Az összes olyan sztring esetében, amely nem tartalmazza a
new_line-t (de idézőjel, azaz"karakterrel kezdődhet vagy végződhet), lehetséges legyen a karakterláncot egyetlen sorban ábrázolni. További részletekért lásd a bővített javaslatot aDrawbacksszakaszban.
- A további összetettség mellett finomíthatjuk a következőt: Az összes olyan sztring esetében, amely nem tartalmazza a
Részletes kialakítás (nem interpolációs eset)
Új string_literal-termelést adunk hozzá a következő formában:
string_literal
: regular_string_literal
| verbatim_string_literal
| raw_string_literal
;
raw_string_literal
: single_line_raw_string_literal
| multi_line_raw_string_literal
;
raw_string_literal_delimiter
: """
| """"
| """""
| etc.
;
raw_content
: not_new_line+
;
single_line_raw_string_literal
: raw_string_literal_delimiter raw_content raw_string_literal_delimiter
;
multi_line_raw_string_literal
: raw_string_literal_delimiter whitespace* new_line (raw_content | new_line)* new_line whitespace* raw_string_literal_delimiter
;
not_new_line
: <any unicode character that is not new_line>
;
A raw_string_literal végződő elválasztónak meg kell egyeznie a kezdő elválasztóval. Tehát ha a kezdő elválasztó """"" a záró elválasztónak is az kell lennie.
Egy raw_string_literal fenti nyelvtanát a következőképpen kell értelmezni:
- Legalább három idézőjellel kezdődik (de nincs felső határa az idézőjeleknek).
- Ezután a tartalom ugyanazon a soron folytatódik, ahol a nyitó idézőjelek kezdődtek. Ezek a tartalmak ugyanazon a soron lehetnek üresek vagy nem üresek. Az "üres" a "teljesen üres tér" szinonimája.
- Ha az ugyanazon a sorban lévő tartalom nem üres, további tartalom nem követhető. Más szóval a literálnak ugyanannak a sornak ugyanannyi idézőjellel kell végződnie.
- Ha az adott sor tartalma üres, akkor a literál folytatódhat
new_line-val és néhány további tartalomsorral ésnew_line-el.- A tartalomvonal bármilyen szöveg, kivéve a
new_line. - Ezután egy
new_linewhitespacebizonyos számával (esetleg nulla), és ugyanannyi idézőjellel, amennyivel a literál kezdődött.
- A tartalomvonal bármilyen szöveg, kivéve a
Nyers sztringkonstans értéke
A kezdő és a záró raw_string_literal_delimiter közötti részek a raw_string_literal értékét a következő módon alakítják ki:
- A
single_line_raw_string_literalesetében a literál értéke pontosan a kezdő és a záróraw_string_literal_delimiterközötti tartalom lesz. - A
multi_line_raw_string_literalesetében a kezdetiwhitespace* new_lineés a végsőnew_line whitespace*nem része a sztring értékének. Awhitespace*terminál előtti utolsóraw_string_literal_delimiterrész azonban "behúzási üres térnek" minősül, és hatással lesz a többi sor értelmezésére. - A végső érték eléréséhez a
(raw_content | new_line)*sorozaton végighaladva a következőket hajtják végre:- Ha a
new_linevan érvényben, anew_linetartalma hozzáadódik a végső sztringértékhez. - Ha nem "üres"
raw_content(azaznot_new_line+nemwhitespacekaraktert tartalmaz):- A behúzási szóköznek a
raw_contentelőtagjának kell lennie. Ez egyébként hiba. - a "behúzási üres tér" a
raw_contentkezdetétől lesz eltávolítva, a fennmaradó rész pedig hozzáadódik a végső sztringértékhez.
- A behúzási szóköznek a
- Ha "üres"
raw_content(azaznot_new_line+teljes egészébenwhitespace):- a 'behúzási szóköznek' a
raw_contentelőtagjának kell lennie, vagy araw_content-nek a 'behúzási szóköz' előtagjának kell lennie. Ez egyébként hiba. - A behúzási szóközök nagy része el van távolítva
raw_contentkezdetéről, és a fennmaradó rész hozzáadódik a végső karakterlánc értékéhez.
- a 'behúzási szóköznek' a
- Ha a
Pontosítások:
A
single_line_raw_string_literalnem képesnew_lineértékkel rendelkező sztringet ábrázolni. Asingle_line_raw_string_literalnem vesz részt a behúzásnál használt szóközök eltávolításában. Értéke mindig a kezdő és a záró elválasztó karakter közötti pontos karakter.Mivel egy
multi_line_raw_string_literalfigyelmen kívül hagyja az utolsó tartalomsor zárónew_line-et, az alábbiak egy olyan sztringet jelölnek, amely nem kezdődiknew_line-vel és nem végződiknew_line-mal.
var v1 = """
This is the entire content of the string.
""";
Ez fenntartja a szimmetriát azáltal, hogy a kezdő new_line figyelmen kívül van hagyva, és egységes módot biztosít arra, hogy a behúzási szóköz mindig módosítható legyen. Egy sztring new_line terminállal való reprezentálásához egy további sort kell megadni a következőképpen:
var v1 = """
This string ends with a new line.
""";
A
single_line_raw_string_literalnem jelölhetnek idézőjellel kezdődő vagy végződő sztringértéket ("), de a javaslat kiegészítését aDrawbacksszakaszban találja, amely bemutatja, hogyan lehet ezt támogatni.A
multi_line_raw_string_literalawhitespace* new_line-t követően araw_string_literal_delimiter-gyel kezdődik. Ez a tartalom az elválasztó után teljesen figyelmen kívül lesz hagyva, és semmilyen módon nem használatos a sztring értékének meghatározásakor. Ez lehetővé teszi, hogy egy mechanizmus olyanraw_string_literaladjon meg, amelynek tartalma egy"karakterrel kezdődik. Például:
var v1 = """
"The content of this string starts with a quote
""";
- A
raw_string_literalidézőjellel végződő tartalmat (") is jelölhetnek. Ez támogatott, mivel a lezáró elválasztónak a saját sorában kell lennie. Például:
var v1 = """
"The content of this string starts and ends with a quote"
""";
var v1 = """
""The content of this string starts and ends with two quotes""
""";
- Annak a követelménynek, hogy az "üres"
raw_contenta behúzási szabad tér előtagja legyen, vagy a behúzási szabad tér előtagjának kell lennie, segít biztosítani, hogy a vegyes térközrel kapcsolatos zavaros forgatókönyvek ne forduljanak elő, különösen azért, mert nem egyértelmű, hogy mi történjen ezzel a vonallal. A következő eset például illegális:
var v1 = """
Start
<tab>
End
""";
Itt a "behúzási szóköz" kilenc szóköz karakterből áll, de az "üres"
raw_contentnem ezzel az előtaggal kezdődik. Nincs egyértelmű válasz arra, hogy ezt a<tab>sort egyáltalán hogyan kell kezelni. Figyelmen kívül kell hagyni? Legyen ugyanaz, mint.........<tab>? Ezért az illegálissá tétel tűnik a legtisztábbnak a félreértések elkerülése érdekében.A következő esetek helyesek, és ugyanazt a karakterláncot képviselik:
var v1 = """
Start
<four spaces>
End
""";
var v1 = """
Start
<nine spaces>
End
""";
Mindkét esetben a „behúzási szóköz” kilenc szóköz lesz. És mindkét esetben eltávolítjuk a lehető legtöbb előtagot, így az "üres" raw_content minden esetben üres lesz (nem számolva minden new_line). Ez lehetővé teszi a felhasználóknak, hogy e sorok másolása/beillesztése vagy szerkesztése során ne kelljen látniuk és aggódniuk a szóköz miatt ezeken a sorokon.
- Abban az esetben azonban:
var v1 = """
Start
<ten spaces>
End
""";
A behúzási szabad tér továbbra is kilenc szóköz lesz. Itt viszont eltávolítjuk a lehető legtöbb "behúzási szóközt", és az "üres" raw_content egyetlen szóközzel járul hozzá a végső szöveghez. Ez lehetővé teszi azokat az eseteket, amikor a tartalomnak ezeken a vonalakon szabad térközre van szüksége, amelyeket meg kell őrizni.
- Az alábbiak technikailag nem jogiak:
var v1 = """
""";
Ennek az az oka, hogy a nyers sztring elejének new_line kell lennie (ami igen), de a végén is new_line kell lennie (ami nem). A minimális legális raw_string_literal a következő:
var v1 = """
""";
Ez a karakterlánc azonban határozottan érdektelen, mivel egyenértékű "".
Példák behúzásra
A "behúzási szóköz" algoritmus többféle bemeneten is így ábrázolható. Az alábbi példák a függőleges sáv karakterének | használatával szemléltetik az első oszlopot az eredményül kapott nyers sztringben:
1. példa – Standard eset
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
a rendszer a következőképpen értelmezi:
var xml = """
|<element attr="content">
| <body>
| </body>
|</element>
""";
2. példa – Végpontelválasztó ugyanazon a sorban, mint a tartalom.
var xml = """
<element attr="content">
<body>
</body>
</element>""";
Ez illegális. Az utolsó tartalomsornak new_line-val kell végződnie.
3. példa – Véghatároló a kezdő határoló előtt
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
a rendszer a következőképpen értelmezi:
var xml = """
| <element attr="content">
| <body>
| </body>
| </element>
""";
4. példa – Véghatároló a kezdőelválasztó után
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
Ez illegális. A tartalom sorainak a "behúzási ürességgel" kell kezdődniük
5. példa – Üres üres sor
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
a rendszer a következőképpen értelmezi:
var xml = """
|<element attr="content">
| <body>
| </body>
|
|</element>
""";
6. példa – Az előtagnál kevesebb üres sor (a pont szóközöket jelöl)
var xml = """
<element attr="content">
<body>
</body>
....
</element>
""";
a rendszer a következőképpen értelmezi:
var xml = """
|<element attr="content">
| <body>
| </body>
|
|</element>
""";
7. példa – Az előtagnál több szóközt tartalmazó üres sor (a pont szóközöket jelöl)
var xml = """
<element attr="content">
<body>
</body>
..............
</element>
""";
a rendszer a következőképpen értelmezi:
var xml = """
|<element attr="content">
| <body>
| </body>
|....
|</element>
""";
Részletes kialakítás (interpolációs eset)
A normál interpolált sztringekben (például $"...") az interpolációk ma támogatottak a { karakter használatával egy interpolation elindításához, valamint egy {{ feloldósorozat használatával egy tényleges nyitott kapcsos karakter beszúrásához. Ugyanez a mechanizmus megsértené a javaslat "1" és "2" céljait. A { alapvető karakterrel (például JavaScript, JSON, Regex és még beágyazott C#) rendelkező nyelveknek most el kell menekülnie, visszavonva a nyers sztringkonstansok célját.
Az interpolációk támogatásához a normál $" interpolált sztringektől eltérő módon vezetjük be őket. Pontosabban egy interpolated_raw_string_literal néhány $ karakterrel kezdődik. Ezek száma azt jelzi, hogy hány { (és }) karakterre van szükség a literál tartalmában a interpolationelválasztásához. Fontos, hogy továbbra sincs menekülési mechanizmus a kapcsos zárójelekhez. Az idézőjelekhez (") hasonlóan maga a konstans is mindig biztosíthatja, hogy az interpolációk olyan elválasztójeleket adjanak meg, amelyek biztosan nem ütköznek a sztring többi tartalmának egyikével sem. Az interpolációs lyukakat tartalmazó JSON-literál például így írható:
var v1 = $$"""
{
"orders":
[
{ "number": {{order_number}} }
]
}
"""
Itt a {{...}} megegyezik a $$ elválasztó előtag által megadott két kapcsos zárójel szükséges számával. Egyetlen $ esetén ez azt jelenti, hogy az interpoláció ugyanúgy van megadva {...}-ként, mint a normál beillesztett karaktersorozatokban. Fontos, hogy ez azt jelenti, hogy az interpolált literál N$ karakterekkel 2*N-1 kapcsos zárójelek sorozatával rendelkezhet (egy sorban azonos típusú). Az utolsó N kapcsos zárójel interpolációt indít (vagy zár be), a többi N-1 kapcsos zárójel pedig csak tartalom lesz. Például:
var v1 = $$"""X{{{1+1}}}Z""";
Ebben az esetben a belső két {{ és }} kapcsos zárójel az interpolációhoz tartozik, és a külső egyes számú kapcsos zárójel csak a tartalom része. A fenti karakterlánc egyenértékű tehát a X{2}Ztartalommal. A 2*N (vagy több) zárójel használata mindig hiba. Ha tartalomként hosszabb kapcsos zárójeleket szeretne létrehozni, a $ karakterek számát ennek megfelelően növelni kell.
Az interpolált nyers sztringkonstansok a következőképpen vannak definiálva:
interpolated_raw_string_literal
: single_line_interpolated_raw_string_literal
| multi_line_interpolated_raw_string_literal
;
interpolated_raw_string_start
: $
| $$
| $$$
| etc.
;
interpolated_raw_string_literal_delimiter
: interpolated_raw_string_start raw_string_literal_delimiter
;
single_line_interpolated_raw_string_literal
: interpolated_raw_string_literal_delimiter interpolated_raw_content raw_string_literal_delimiter
;
multi_line_interpolated_raw_string_literal
: interpolated_raw_string_literal_delimiter whitespace* new_line (interpolated_raw_content | new_line)* new_line whitespace* raw_string_literal_delimiter
;
interpolated_raw_content
: (not_new_line | raw_interpolation)+
;
raw_interpolation
: raw_interpolation_start interpolation raw_interpolation_end
;
raw_interpolation_start
: {
| {{
| {{{
| etc.
;
raw_interpolation_end
: }
| }}
| }}}
| etc.
;
A fentiek hasonlóak a raw_string_literal definícióhoz, de néhány fontos különbséggel. A interpolated_raw_string_literal a következőképpen kell értelmezni:
- Legalább egy dollárjellel (de felső határ nélkül) kezdődik, majd három idézőjellel (szintén felső határ nélkül).
- Ezután a kezdő idézőjelekkel azonos sorban lévő tartalommal folytatódik. Az ugyanazon a sorban lévő tartalom lehet üres vagy nem üres. Az "üres" a "teljesen üres tér" szinonimája.
- Ha az ugyanazon a sorban lévő tartalom nem üres, további tartalom nem követhető. Más szóval a literálnak ugyanannak a sornak ugyanannyi idézőjellel kell végződnie.
- Ha az adott sor tartalma üres, akkor a literál folytatódhat
new_line-val és néhány további tartalomsorral ésnew_line-el.- A tartalomvonal bármilyen szöveg, kivéve a
new_line. - A tartalomsorok tetszőleges helyen több
raw_interpolationelőfordulást tartalmazhatnak. Araw_interpolationegyenlő számú nyitott kapcsos zárójeltel ({) kell kezdődnie, mint a literál elején lévő dollárjelek száma. - Ha a behúzás szóköz nem üres, a
raw_interpolationnem követheti közvetlenül anew_line-et. - A
raw_interpolationa normál szabályokat követi majd, amelyeket a §12.8.3.-ban határoztak meg. Mindenraw_interpolationa dollárjelekkel és a nyitott kapcsos zárójelekkel megegyező számú szoros kapcsos zárójeltel (}) kell végződnie. - Bármely
interpolationugyanúgy tartalmazhat új sorokat, mint ahogy azt egy normálinterpolation(verbatim_string_literal)@""esetében megszokhattuk. - Ezután egy
new_linewhitespacebizonyos számával (esetleg nulla), és ugyanannyi idézőjellel, amennyivel a literál kezdődött.
- A tartalomvonal bármilyen szöveg, kivéve a
Az interpolált sztringérték számítása ugyanazokat a szabályokat követi, mint a normál raw_string_literal, de kiegészítve a raw_interpolation-et tartalmazó sorok kezelésére. A karakterlánc érték létrehozása ugyanolyan módon történik, azzal a különbséggel, hogy az interpolációs helyek a kifejezések által futásidőben előállított értékekkel kerülnek kicserélésre. Ha a interpolated_raw_string_literalFormattableString lesz konvertálva, akkor az interpolációk értékei a megfelelő sorrendben lesznek átadva a arguments tömbnek FormattableString.Create. A interpolated_raw_string_literal után, miután a "behúzási szóközöket" eltávolították az összes sorból, a fennmaradó tartalmak a formatszámára átadott FormattableString.Create sztring létrehozásához lesznek felhasználva, ahol a megfelelően számozott {N} tartalmak kerülnek minden olyan helyre, ahol raw_interpolation történt (vagy {N,constant} abban az esetben, ha interpolationexpression ',' constant_expressionformájú).
A fenti specifikáció kétértelmű. Különösen akkor, amikor a { egy szakasza és a { egy interpoláció találkoznak a szövegben. Például:
var v1 = $$"""
{{{order_number}}}
"""
Ez a következőképpen értelmezhető: {{ {order_number } }} vagy { {{order_number}} }. Mivel azonban az előbbi illegális (a C#-kifejezés nem kezdődhet {) értelmetlen lenne így értelmezni. Tehát az utóbbi módon értelmezzük, ahol a legbelső { és } kapcsos zárójelek alkotják az interpolációt, és a legkülsőek alkotják a szöveget. A jövőben ez problémát jelenthet, ha a nyelv valaha is támogatja a kapcsos zárójelek által körülvett kifejezéseket. Ebben az esetben azonban az lenne a javaslat, hogy írjon egy ilyen esetet: {{({some_new_expression_form})}}. Itt a zárójelek segítenek kijelölni a kifejezésrészt a literál/interpoláció többi részéből. Ez már eleve elsőbbséget élvez azzal, hogy a ternáris feltételes kifejezéseket be kell burkolni, hogy ne ütközhessenek az interpoláció formázási/igazítási megjelölőjével (például {(x ? y : z)}).
Hátránya
A nyers karakterlánc-literalok összetettebbé teszik a nyelvet. Már számos sztringkonstans formátumunk van számos célra.
"" karakterláncok, @"" karakterláncok és $"" karakterláncok már nagy teljesítményűek és rugalmasak. Mindegyikből hiányzik egy mód arra, hogy nyers tartalmat adjanak meg, amelyet soha nem kell levédeni vagy átalakítani.
A fenti szabályok nem támogatják a 4.aesetét:
- ...
- A további összetettség mellett finomíthatjuk a következőt: Az összes olyan sztring esetében, amely nem tartalmazza a
new_line-t (de idézőjel, azaz"karakterrel kezdődhet vagy végződhet), lehetséges legyen a karakterláncot egyetlen sorban ábrázolni.
- A további összetettség mellett finomíthatjuk a következőt: Az összes olyan sztring esetében, amely nem tartalmazza a
Ennek az az oka, hogy nem tudjuk, hogy egy kezdő vagy záró idézőjelnek (") a tartalomhoz kell tartoznia, és nem magának a határolónak. Ha ez egy fontos forgatókönyv, amelyet támogatni szeretnénk, hozzáadhatunk egy párhuzamos ''' szerkezetet, amely párhuzamosan működik a """ formával. Ezzel a párhuzamos szerkezettel a " kezdő és végződő egysoros sztring egyszerűen írható '''"This string starts and ends with quotes"''' a párhuzamos szerkezettel együtt """'This string starts and ends with apostrophes'""". Ez is kívánatos lehet az idézőjelek vizuális elválasztásához, ami segíthet az olyan nyelvek beágyazásakor, amelyek elsősorban egy idézőjelet használnak, sokkal jobban, mint a többi.
Alternatívák
https://github.com/dotnet/csharplang/discussions/89 számos lehetőséget lefed itt. Számos alternatíva létezik, de úgy érzem, hogy azok túlságosan a túlzott bonyolultság és gyenge ergonómia irányába vezetnek. Ez a megközelítés az egyszerűséget választja, ahol csak tovább növeli a kezdő/záró idézőjel hosszát, amíg nem kell aggódni a karakterlánc tartalmával való ütközés miatt. Emellett lehetővé teszi, hogy az ön által írt kód megfelelően legyen behúzva, miközben létrehoz egy levont behúzású literált, amely a legtöbb kód számára szükséges.
Az egyik legérdekesebb lehetséges variáció azonban a ` (vagy ```) kerítések használata ezekhez a nyers sztring literálokhoz. Ennek több előnye is lehet:
- Kerülné a idézőjelekkel kezdődő vagy végződő karakterláncok összes problémáját.
- A megjelenése hasonló lenne a Markdownhoz. Bár ez önmagában valószínűleg nem jó dolog, mivel a felhasználók markdown-értelmezésre számíthatnak.
- A nyers sztringkonstansnak a legtöbb esetben csak egyetlen karakterrel kellene kezdődnie és végződnie, és csak a sokkal ritkábban használt tartalom esetében lenne szükség többre, amelyek magukban a visszajeleket tartalmazzák.
- Természetesnek tűnne, hogy a jövőben ezt kiterjesszük
```xml-val, ismét hasonlóan a Markdownhoz. Bár, persze, ez is igaz a"""formában.
Összességében azonban a nettó előny itt kicsinek tűnik. A C# előzményeinek megfelelően azt hiszem, " továbbra is a string literal elválasztónak kell lennie, ugyanúgy, mint @"" és $"".
Tervezői értekezletek
Megvitatandó nyitott kérdések Megoldott kérdések
- [x] legyen egy egysoros űrlapunk? Gyakorlatilag nélküle is megtehetnénk. De ez azt jelentené, hogy az egyszerű sztringek, amelyek nem tartalmaznak új vonalat, mindig legalább három sort vesznek igénybe. Azt hiszem, nagyon nehéz lenne kényszeríteni az egysoros szerkezeteket, hogy három vonal legyen csak azért, hogy elkerülje a menekülést.
Tervezési döntés: Igen, egysoros űrlapot fogunk létrehozni.
- [x] Megköveteljük-e, hogy a többsoros -nak új sorban kelljen kezdődnie? Szerintem kellene. Az is lehetővé teszi számunkra a jövőben, hogy olyan dolgokat támogassunk, mint a
"""xml.
Tervezési döntés: Igen, azt követeljük meg, hogy a többsoros vonalnak egy új vonallal kell kezdődnie
- [x] szükséges egyáltalán az automatikus dedentálás? Szerintem kellene. Sokkal kellemesebb megjelenésűvé teszi a kódot.
Tervezési döntés: Igen, az automatikus dedentálás megtörténik.
- [x] korlátoznunk kell a közös térközt a térköztípusok keveredéséből? Nem hiszem, hogy kellene. Létezik egy gyakori behúzási stratégia, az úgynevezett "tabulátor a behúzáshoz, szóköz az igazításhoz". Nagyon természetes lenne ezt arra használni, hogy a véghatárolót igazítsuk a kezdőhatárolóhoz, amikor a kezdőhatároló nem tabulátoron kezdődik.
Tervezési döntés: A szabad tér keverésére semmilyen korlátozás nem vonatkozik.
- [x] használjunk valami mást a kerítésekhez?
`megegyezne a Markdown szintaxisával, és azt jelentené, hogy nem kell mindig három idézőjellel kezdeni ezeket a sztringeket. Csak egy elég lenne a gyakori esethez.
Tervezési döntés: A """-t fogjuk használni.
- Legyen az a követelmény, hogy a határoló több idézőjelet tartalmazzon, mint a szövegérték leghosszabb idézőjelsorozata? Technikailag ez nem kötelező. például:
var v = """
contents"""""
"""
Ez egy karakterlánc, amelyben a határoló karakter a """. Több közösségtag is kijelentette, hogy ez zavaró, és ilyen esetekben megköveteljük, hogy a határolónak mindig több karakterből kell állnia. Ez a következő lenne:
var v = """"""
contents"""""
""""""
Tervezési döntés: Igen, a határolónak hosszabbnak kell lennie, mint bármely idézőjelek sorozata a sztringen belül.
C# feature specifications