Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Not
Bu makale bir özellik belirtimidir. Belirtim, özelliğin tasarım belgesi olarak görev alır. Önerilen belirtim değişikliklerini ve özelliğin tasarımı ve geliştirilmesi sırasında gereken bilgileri içerir. Bu makaleler, önerilen belirtim değişiklikleri son haline getirilene ve geçerli ECMA belirtimine dahil edilene kadar yayımlanır.
Özellik belirtimi ile tamamlanan uygulama arasında bazı tutarsızlıklar olabilir. Bu farklılıklar, ilgili dil tasarım toplantısı (LDM) notlarındayer alır.
Özellik belirtimlerini C# dil standardına benimseme işlemi hakkında daha fazla bilgi edinmek için
Şampiyon sorunu: https://github.com/dotnet/csharplang/issues/8647
Özet
En az üç """ karakterle başlayan (ama maksimum bir sayı yok), isteğe bağlı olarak bir new_lineile devam eden, ardından dize içeriği gelen ve en sonunda değişmez değerin başladığı sayıda tırnak işaretiyle biten yeni bir dize değişmez değeri biçimine izin verin. Mesela:
var xml = """
<element attr="content"/>
""";
İç içe yerleştirilmiş içerik """ kullanmak isteyebileceğinden, başlangıç/bitiş sınırlayıcıları daha uzun olabilir, bu nedenle:
var xml = """"
Ok to use """ here
"""";
Metnin okunmasını kolaylaştırmak ve geliştiricilerin kodda beğendikleri girintilere izin vermek için, bu string literalleri son verilen değeri oluştururken son satırda belirtilen girintiyi doğal olarak kaldırır. Örneğin, şu biçimde bir sabit değer:
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
İçeriğe sahip olacak:
<element attr="content">
<body>
</body>
</element>
Bu, kodun doğal görünmesini sağlarken, istenen metin sabitlerini üretmeye devam eder ve özel dize işleme yordamlarının kullanılmasını gerektiriyorsa çalışma zamanı maliyetlerini azaltır.
Girintileme davranışı istenmiyorsa, aşağıdaki gibi devre dışı bırakmak da kolaydır:
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
Tek satırlı form da desteklenir. En az üç """ karakterle başlar (maksimum sınır yoktur), dizenin içeriğiyle (new_line karakter içeremez) devam eder ve başladığı alıntı işareti sayısıyla biter. Mesela:
var xml = """<summary><element attr="content"/></summary>""";
İşlenmiş ham metinler de desteklenir. Bu durumda dize, bir iç içe yerleştirme başlatmak için gereken ayraç sayısını belirtir (literalin başında bulunan dolar işareti sayısına göre belirlenir). Bundan daha az küme ayracı içeren küme ayracı dizisi yalnızca içerik olarak değerlendirilir. Mesela:
var json = $$"""
{
"summary": "text",
"length" : {{value.Length}},
};
""";
Motivasyon
C#, her türlü metni etkili bir şekilde içerebilen basit dize sabitleri oluşturmak için genel bir yönteme sahip değildir. Günümüzde tüm C# string literal biçimleri, içeriğin özel bir karakter kullanması durumunda bir tür kaçış biçimine ihtiyaç duyar (her zaman bir ayraç kullanılırsa). Bu, başka dilleri içeren değişmez değerlerin (örneğin, XML, HTML veya JSON değişmez değeri) kolayca oluşmasını önler.
Bugün C# dilinde bu değişmez değerleri oluşturmaya yönelik tüm geçerli yaklaşımlar, kullanıcıyı her zaman içerikten el ile kaçmaya zorlar. Bu noktada düzenleme son derece can sıkıcı olabilir çünkü kaçış durumu önlenemez ve içerikte ortaya çıktığında bu durumla başa çıkılması gerekir. Bu, özellikle tırnak işaretleri veya ters eğik çizgi içeren reex'ler için çok acı vericidir. Düz metin (@"") dizesinde bile tırnak işaretleri kaçış karakteri ile belirtilmelidir ve bu, C# ve regex'in birbirine karışmasına neden olabilir.
{ ve }, interpolasyonlu ($"") dizelerde benzer şekilde sinir bozucudur.
Sorunun en önemli noktası, tüm dizelerimizin sabit bir başlangıç/bitiş sınırlayıcısına sahip olmasıdır. Bu durum söz konusu olduğu sürece, dize içeriğinin içeriklerinde bu uç sınırlayıcıyı belirtmesi gerekebileceği için her zaman bir kaçış mekanizmasına sahip olmamız gerekir. Sınırlayıcı " birçok dilde giderek yaygın olduğu için bu durum özellikle sorunludur.
Bunu ele almak için, bu teklif esnek başlangıç ve bitiş sınırlayıcılarına olanak tanır, böylece her zaman dizenin içeriğiyle çakışmayacak bir şekilde yapılabilirler.
Hedef
- Herhangi bir
kaçış dizisine gerek kalmadan tüm dize değerlerinin kullanıcı tarafındanizin veren bir mekanizma sağlayın. Tüm dizelerin kaçış dizileri olmadan gösterilebilir olması gerektiğinden, kullanıcının herhangi bir metin içeriğiyle harmanlanmaması garanti edilecek sınırlayıcıları belirtmesi her zaman mümkün olmalıdır. - Enterpolasyonları aynı şekilde destekleyin. Yukarıdaki gibi, tüm dizeleri kaçış karakteri kullanmadan temsil edilebilmesi gerektiğinden, kullanıcının herhangi bir metin içeriğiyle çakışmaması garanti edilecek bir
interpolationsınırlayıcısı belirtmesi her zaman mümkün olmalıdır. Daha da önemlisi, ilişkilendirme sınırlayıcı karakterlerimizi ({ve}) kullanan diller birinci sınıf hissetmeli ve kullanımı zor olmamalıdır. - Çoksatırlı dizgi sabitleri, kod içinde hoş görünmeli ve derleme birimi içindeki girintilemeyi garip göstermemelidir. Önemli bir nokta olarak, kendilerinde girinti olmayan değişmez değerlerin dosyanın ilk sütununda yer alması için zorlanmaması gerekir; bu, kodun akışını bozabilir ve etrafındaki diğer kodla uyumsuz görünmesine neden olabilir.
- Yazılı sabitlerin net ve kolay okunmasını sağlarken bu davranışın geçersiz kılınması kolay olmalıdır.
-
new_lineiçermeyen ve bir tırnak işareti (") karakteriyle başlamayan veya bitmeyen tüm dizeler için, dize değişmez değerinin kendisini tek bir satırda temsil etmek mümkün olmalıdır.- İsteğe bağlı olarak, ek karmaşıklık ile bunu şu şekilde daraltabiliriz: Kendileri
new_lineiçermeyen tüm dizeler için (ancak bir tırnak"karakteri ile başlayabilir veya bitebilir), dize değişmez değerinin tek bir satırda temsil edilmesi mümkün olmalıdır. Daha fazla ayrıntı içinDrawbacksbölümündeki genişletilmiş teklife bakın.
- İsteğe bağlı olarak, ek karmaşıklık ile bunu şu şekilde daraltabiliriz: Kendileri
Ayrıntılı tasarım (interpolasyon dışı durum)
Aşağıdaki formda yeni bir string_literal üretim ekleyeceğiz:
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>
;
Bir raw_string_literal bitiş sınırlayıcısı, başlangıç sınırlayıcısıyla eşleşmelidir. Dolayısıyla başlangıç sınırlayıcısı """"" bitiş sınırlayıcısı da bu şekilde olmalıdır.
Bir raw_string_literal için yukarıdaki dil bilgisi şu şekilde yorumlanmalıdır:
- Üçten fazla tırnak işareti ile başlar, ancak tırnak işaretleri için üst sınır yoktur.
- Ardından başlangıç tırnaklarıyla aynı satırdaki içeriklerle devam eder. Aynı satırdaki bu içerikler boş veya boş olmayabilir. 'blank', 'tamamen boşluk' ile eş anlamlıdır.
- Aynı satırdaki içerik boş değilse, başka içerik takip edemez. Başka bir deyişle, literal ifadenin aynı satırda aynı sayıda tırnak işaretiyle bitmesi gerekir.
- Aynı satırdaki içerik boşsa, literal
new_lineve bazı sonraki içerik satırları ilenew_line'lerle devam edebilir.- İçerik satırı,
new_linedışında herhangi bir metindir. - Daha sonra
new_linebir sayı (muhtemelen sıfır)whitespaceve değişmez değerin başladığı aynı sayıda tırnak işaretiyle sona erer.
- İçerik satırı,
Ham dize sabit değeri
Başlangıç ve bitiş raw_string_literal_delimiter arasındaki bölümler, raw_string_literal değerini aşağıdaki şekilde oluşturmak için kullanılır:
-
single_line_raw_string_literaldurumunda, literal değeri tam olarak başlangıç ve bitişraw_string_literal_delimiterarasındaki içeriği kapsar. -
multi_line_raw_string_literaldurumunda, başlangıçtakiwhitespace* new_lineve sondakinew_line whitespace*dizenin değerinin bir parçası değildir. Ancak,whitespace*terminalden önceki sonraw_string_literal_delimiterbölümü 'girinti boşluğu' olarak kabul edilir ve diğer satırların yorumlanma şeklini etkiler. - Son değeri almak için
(raw_content | new_line)*dizisine geçilir ve aşağıdakiler gerçekleştirilir:- Bu bir
new_lineise,new_lineiçeriği son dize değerine eklenir. - 'Boş' bir
raw_contentdeğilse (not_new_line+whitespaceolmayan bir karakter içerir):- 'Girinti boşluğu'
raw_content'nin bir ön eki olmalıdır. Aksi takdirde bir hatadır. - 'girinti boşluğu'
raw_contentbaşından çıkarılır ve kalan değer son dize değerine eklenir.
- 'Girinti boşluğu'
- 'Boş' bir
raw_contentise (yaninot_new_line+tamamenwhitespace):- 'girinti boşluğu'
raw_content'ın ön eki olmalı veyaraw_content'girinti boşluğu'nun ön eki olmalıdır. Aksi takdirde bir hatadır. - 'indentation whitespace' değerinin çoğu
raw_contentbaşlangıcından çıkarılır ve kalan tüm değerler son dize değerine eklenir.
- 'girinti boşluğu'
- Bu bir
Açıklamalar:
bir
single_line_raw_string_literal, içindenew_linedeğeri olan bir dizeyi temsil etme yeteneğine sahip değildir. Birsingle_line_raw_string_literal, 'girinti boşluğu' kırpma işlemine katılmaz. Değeri her zaman başlangıç ve bitiş sınırlayıcıları arasındaki tam karakterlerdir.Son içerik satırının son
multi_line_raw_string_literal'ini birnew_linegöz ardı ettiğinden, aşağıdakiler başlangıçtanew_lineve sondanew_lineolmayan bir dizeyi temsil eder.
var v1 = """
This is the entire content of the string.
""";
Bu, başlangıç new_line'nin nasıl göz ardı edildiğine dair dengeyi korur ve ayrıca 'girinti boşluğunu' her zaman ayarlayabilmek için tutarlı bir yöntem sağlar. Bir terminal new_line dizesini temsil etmek için aşağıdaki gibi ek bir satır verilmelidir:
var v1 = """
This string ends with a new line.
""";
single_line_raw_string_literal, tırnak ile başlayan veya biten bir dize değerini temsil edemez ("), ancak bunun nasıl desteklenebileceğini gösterenDrawbacksbölümünde bu öneriye yönelik bir genişletme sağlanır.multi_line_raw_string_literal, ilkwhitespace* new_line'yi takibenraw_string_literal_delimiterile başlar. Sınırlayıcıdan sonraki bu içerik tamamen yoksayılır ve dizenin değeri belirlenirken hiçbir şekilde kullanılmaz. Bu, içeriğiraw_string_literalkarakteriyle başlayan bir"belirtme mekanizmasına olanak tanır. Mesela:
var v1 = """
"The content of this string starts with a quote
""";
-
raw_string_literal, tırnak işaretiyle biten içeriği de temsil edebilir ("). Sonlandırıcı sınırlayıcının kendi satırında olması gerektiğinden bu desteklenir. Mesela:
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""
""";
- Gereksinim, 'Boş'
raw_content'nın ya 'girinti boşluğu'nun ön eki olması gerektiği ya da 'girinti boşluğu'nun onun ön eki olması gerektiğine dair. Bu, özellikle bu satırda ne olacağı belirsiz kalacağından, karmaşık boşluk senaryolarının oluşmamasını sağlamaya yardımcı olur. Örneğin, aşağıdaki durum geçersizdir:
var v1 = """
Start
<tab>
End
""";
Burada 'girinti boşluğu' dokuz boşluk karakteridir, ancak 'boş'
raw_contentbunun ön ekiyle başlamaz. Bu<tab>satırın nasıl ele alınması gerektiğine dair net bir yanıt yoktur. Göz ardı mı edilsin?.........<tab>ile aynı mı olmalı? Bu nedenle, yasa dışı hale getirmek karışıklığı önlemek için en açık görünüyor.Ancak aşağıdaki durumlar yasaldır ve aynı dizeyi temsil ediyor:
var v1 = """
Start
<four spaces>
End
""";
var v1 = """
Start
<nine spaces>
End
""";
Her iki durumda da 'girinti boşluğu' dokuz boşluk olacaktır. Ve her iki durumda da, bu ön ekin mümkün olduğunca çoğunu kaldıracağız ve her durumda 'boş' raw_content boş olacak (her new_linesayılmıyor). Bu, kullanıcıların bu satırları kopyaladıkları/yapıştırdıkları veya düzenledikleri zaman bu satırlardaki boşluğu görmelerine ve bu boşluklar hakkında endişelenmelerine gerek olmamasını sağlar.
- Ancak, şu durumlarda:
var v1 = """
Start
<ten spaces>
End
""";
'Girinti boşluğu' yine dokuz boşluk olarak kalacaktır. Ancak burada mümkün olduğunca 'girinti boşluklarını' kaldıracağız ve 'boş' raw_content son içeriğe tek bir alan katkıda bulunacaktır. Bu, içeriğin korunması gereken bu satırlarda boşluk gerektirmesi durumlarına olanak tanır.
- Teknik olarak aşağıdakiler yasal değildir:
var v1 = """
""";
Bunun nedeni, ham dizenin başında bir new_line bulunması gerekir (ki bulunur), ancak sonunda da bir new_line bulunması gerekir (ki bulunmaz). En düşük yasal raw_string_literal:
var v1 = """
""";
Ancak, bu dize ""'a eşdeğer olduğundan hiçbir şekilde ilgi çekici değildir.
Girinti örnekleri
'Girinti boşluğu' algoritması, çeşitli girişlerde şöyle görselleştirilebilir. Aşağıdaki örneklerde, sonuçta elde edilen ham dizedeki ilk sütunu göstermek için dikey çubuk karakteri | kullanılır:
Örnek 1 - Standart durum
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
olarak yorumlanır
var xml = """
|<element attr="content">
| <body>
| </body>
|</element>
""";
Örnek 2 - Sınırlayıcıyı içerikle aynı satırda sonlandır.
var xml = """
<element attr="content">
<body>
</body>
</element>""";
Bu yasal değil. Son içerik satırı bir new_lineile bitmelidir.
Örnek 3 - Başlangıç sınırlayıcısından önce bitiş sınırlayıcısı
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
olarak yorumlanır
var xml = """
| <element attr="content">
| <body>
| </body>
| </element>
""";
Örnek 4 - Başlangıç sınırlayıcıdan sonra sınırlayıcıyı sonlandır
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
Bu yasal değil. İçerik satırları 'girinti boşluğu' ile başlamalıdır
Örnek 5 - Boş satır
var xml = """
<element attr="content">
<body>
</body>
</element>
""";
olarak yorumlanır
var xml = """
|<element attr="content">
| <body>
| </body>
|
|</element>
""";
Örnek 6 - Ön ekten daha az boşluk içeren boş satır (noktalar boşlukları temsil eder)
var xml = """
<element attr="content">
<body>
</body>
....
</element>
""";
olarak yorumlanır
var xml = """
|<element attr="content">
| <body>
| </body>
|
|</element>
""";
Örnek 7 - Ön ekten daha fazla boşluk içeren boş satır (noktalar boşlukları temsil eder)
var xml = """
<element attr="content">
<body>
</body>
..............
</element>
""";
olarak yorumlanır
var xml = """
|<element attr="content">
| <body>
| </body>
|....
|</element>
""";
Ayrıntılı tasarım (interpolasyon durumu)
Normal interpolasyonlu dizelerdeki interpolasyonlar (örneğin, $"..."), bugün bir { başlatmak için interpolation karakterinin kullanılması ve gerçek bir açık ayraç karakteri eklemek amacıyla bir {{ kaçış dizisi kullanılması yoluyla desteklenmektedir. Aynı mekanizmanın kullanılması, bu teklifin '1' ve '2' hedeflerini ihlal eder. Çekirdek karakter olarak {'ı kullanan (örnek olarak JavaScript, JSON, Regex ve hatta katıştırılmış C# gibi) diller artık ham dize değişmezlerinin amacını geçersiz kılacak şekilde kaçış karakteri gerektirir.
İlişkilendirmeleri desteklemek için bunları normal $" ilişkilendirilmiş dizelerden farklı bir şekilde tanıtıyoruz. Özellikle, bir interpolated_raw_string_literal belirli sayıda $ karakterle başlar. Bu karakterlerin sayısı, {'yi sınırlandırmak için sabit değerin içeriğinde kaç tane } (ve interpolation) karakterine ihtiyaç olduğunu gösterir. Küme ayraçları için hala bir kaçış mekanizması bulunmamaktadır. Bunun yerine, tırnak işaretleri (") gibi, literal ifadenin kendisi, dize içeriğinin geri kalanıyla çakışmaması kesin olan yerleştirmeler için her zaman sınırlayıcılar belirleyebilir. Örneğin, ilişkilendirme delikleri içeren bir JSON değişmez değeri şöyle yazılabilir:
var v1 = $$"""
{
"orders":
[
{ "number": {{order_number}} }
]
}
"""
Burada {{...}}, $$ sınırlayıcı ön eki tarafından belirtilen iki ayraç parantezinin gerekli sayısıyla eşleşir. Tek bir $ olması durumunda, bu, interpolasyonun, normal interpolasyonlu dize ifadelerinde olduğu gibi, sadece {...} olarak belirtildiği anlamına gelir. Daha da önemlisi, N$ karakter içeren ilişkilendirilmiş bir değişmez değerin 2*N-1 ayraç dizisine (bir satırda aynı türde) sahip olabileceği anlamına gelir. Son N ayraçları bir ilişkilendirme başlatır (veya biter) ve kalan N-1 ayraçları yalnızca içerik olur. Mesela:
var v1 = $$"""X{{{1+1}}}Z""";
Bu durumda içteki iki {{ ve }} parantezi enterpolasyona aittir ve dıştaki tek parantezler yalnızca içeriktir. Bu nedenle yukarıdaki dize, X{2}Ziçerikle eşdeğerdir.
2*N (veya daha fazla) ayraç olması her zaman bir hatadır. İçerik olarak daha uzun ayraç dizilerine sahip olmak için, $ karakter sayısı buna göre artırılmalıdır.
İliştirilmiş ham dize sabitleri şu şekilde tanımlanır:
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.
;
Yukarıdakiler, raw_string_literal tanımına benzer ancak bazı önemli farklılıklara sahiptir. bir interpolated_raw_string_literal şu şekilde yorumlanmalıdır:
- En az bir dolar işaretiyle (ancak üst sınır olmadan) ve ardından üç tırnakla (ayrıca üst sınır olmadan) başlar.
- Daha sonra başlangıç tırnak işaretleriyle aynı satırdaki içerikle devam eder. Aynı satırdaki bu içerik boş veya boş olmayabilir. 'blank', 'tamamen boşluk' ile eş anlamlıdır.
- Aynı satırdaki içerik boş değilse, başka içerik ekleyemezsiniz. Başka bir deyişle, literal ifadenin aynı satırda aynı sayıda tırnak işaretiyle bitmesi gerekir.
- Aynı satırdaki içerik boşsa, literal
new_lineve bazı sonraki içerik satırları ilenew_line'lerle devam edebilir.- İçerik satırı,
new_linedışında herhangi bir metindir. - İçerik satırı herhangi bir konumda birden çok
raw_interpolationifadesi içerebilir.raw_interpolation, değişmez değerin başındaki dolar işareti sayısıyla eşit sayıda açık süslü parantezle ({) başlamalıdır. - 'Girinti boşluğu' boş değilse,
raw_interpolationbirnew_line'i hemen takip edemez. -
raw_interpolation§12.8.3'de belirtilen normal kurallara uyar. Herhangi birraw_interpolation, dolar işaretleri ve açık ayraçlarla aynı sayıda yakın ayraçla (}) bitmelidir. - Herhangi bir
interpolation, normal birinterpolation'nin (verbatim_string_literal) içindeki@""gibi aynı şekilde yeni satırlar içerebilir. - Daha sonra
new_linebir sayı (muhtemelen sıfır)whitespaceve değişmez değerin başladığı aynı sayıda tırnak işaretiyle sona erer.
- İçerik satırı,
Interpolasyonlu dize değerinin hesaplanması, raw_string_literaliçeren satırları işleyecek şekilde güncelleştirilmesi dışında, normal bir raw_interpolation ile aynı kuralları izler. Dize değerinin oluşturulması aynı şekilde gerçekleşir, yalnızca ilişkilendirme delikleri bu ifadelerin çalışma zamanında ürettiği değerlerle değiştirilir.
interpolated_raw_string_literal bir FormattableString'e dönüştürülürse, interpolasyonların değerleri kendi sıralarına göre argumentsiçin FormattableString.Create dizisine geçirilir. 'girinti boşluğu' tüm satırlardan temizlendikten sonra,
Yukarıdaki belirtimlerde bir belirsizlik vardır. Özellikle bir metindeki { bölümü ve bir interpolasyonun {'inin bitişiğinde. Mesela:
var v1 = $$"""
{{{order_number}}}
"""
Bu şu şekilde yorumlanabilir: {{ {order_number } }} veya { {{order_number}} }. Ancak, önceki geçersiz olduğundan (hiçbir C# ifadesi {ile başlayamadı) bu şekilde yorumlamak anlamsız olacaktır. Bu nedenle, en içteki { ve } ayraçlarının ilişkilendirmeyi ve en dıştakilerin metni oluşturduğu ikinci şekilde yorumlarız. Gelecekte, dil parantezlerle çevrili herhangi bir ifadeyi desteklerse, bu bir sorun haline gelebilir. Ancak, bu durumda, şöyle bir durum yazılması önerilir: {{({some_new_expression_form})}}. Burada parantezler, ifade kısmını değişmez değer/metin yerleştirmenin geri kalanından ayırmaya yardımcı olur. Bunun zaten bir ilişkilendirmenin biçimlendirme/hizalama tanımlayıcısıyla çakışmaması için üçüncül koşullu ifadelerin nasıl sarmalanması gerektiğinden önceliklidir (örneğin, {(x ? y : z)}).
Dezavantaj -ları
Ham dize literalleri dile daha fazla karmaşıklık katar. Zaten birçok farklı amaç için birden çok dize sabiti biçimine sahibiz.
"" dizeleri, @"" dizeleri ve $"" dizeleri zaten çok fazla güç ve esnekliğe sahiptir. Ancak hepsi, hiçbir zaman kaçması gerekmeyen ham içerikleri sağlamanın bir yolunu bulamaz.
Yukarıdaki kurallar 4.adurumunu desteklemez:
- ...
- İsteğe bağlı olarak, ek karmaşıklık ile bunu şu şekilde daraltabiliriz: Kendileri
new_lineiçermeyen tüm dizeler için (ancak bir tırnak"karakteri ile başlayabilir veya bitebilir), dize değişmez değerinin tek bir satırda temsil edilmesi mümkün olmalıdır.
- İsteğe bağlı olarak, ek karmaşıklık ile bunu şu şekilde daraltabiliriz: Kendileri
Bunun nedeni, başlangıç veya bitiş tırnaklarının (") sınırlayıcının kendisine değil içeriğine ait olması gerektiğini bilmemize imkan tanımamızdır. Bu, desteklemek istediğimiz önemli bir senaryoysa, ''' formuyla birlikte paralel bir """ yapısı ekleyebiliriz. Bu paralel yapıyla, " ile başlayıp biten tek bir satır dizesi, paralel yapı '''"This string starts and ends with quotes"'''ile birlikte """'This string starts and ends with apostrophes'""" olarak kolayca yazılabilir. Bu, öncelikle bir tırnak karakterini diğerinden çok daha fazla kullanan dilleri eklerken yardımcı olabilecek tırnak karakterlerini görsel olarak ayırmaya yardımcı olmak için de destek istenebilir.
Alternatif
https://github.com/dotnet/csharplang/discussions/89 burada birçok seçeneği kapsar. Alternatifler çok sayıda, ancak aşırı karmaşıklığa ve zayıf ergonomiye kayıyorlar. Bu yaklaşım, dize içeriğiyle çakışma endişesi olmayana kadar başlangıç/bitiş tırnak uzunluğunu artırmaya devam ettiğiniz basitliği tercih eder. Ayrıca, yazdığınız kodun iyi biçimlendirilmiş görünmesini sağlarken, yine de çoğu kodun istediği şekilde, girintisi azaltılmış bir sabit değer üretmeyi sağlar.
Olası en ilginç varyasyonlardan biri, bu ham dize değişmez değerleri için ` (veya ```) sınırlayıcıların kullanılmasıdır. Bunun çeşitli avantajları olabilir:
- Tırnak işaretleri ile başlayan veya biten dizelerle ilgili tüm sorunları önler.
- Markdown'a benzer görünürdü. Ancak bu, kullanıcıların markdown yorumunu bekleyebileceği için potansiyel olarak iyi bir şey değildir.
- Ham dize değişmez değerinin çoğu durumda yalnızca tek bir karakterle başlayıp bitmesi gerekir ve yalnızca içeriğin kendisinin ters tırnak işaretleri içerdiği çok daha nadir durumlarda birden çok karaktere ihtiyaç duyulur.
- Gelecekte bunu
```xmlile genişletmek, markdown'a benzer şekilde doğal olacaktır. Ancak, elbette, bu"""formu için de geçerlidir.
Genel olarak, buradaki net avantaj küçük görünüyor. C# geçmişine uygun olarak, "string literal ve @""için olduğu gibi $"" sınırlayıcı olmaya devam etmelidir.
Tasarım toplantıları
Tartışılacak açık sorunlar: Çözülen sorunlar:
- [x] Tek satırlı bir form olmalı mı? Teknik olarak onsuz da yapabiliriz. Ancak bu, yeni satır içermeyen basit dizelerin her zaman en az üç satır alması anlamına gelir. Bence kaçıştan kaçınmak için tek hatlı yapıları üç satıra zorlamak çok ağır bir şey olmalı.
Tasarım kararı: Evet, tek satırlı bir form olacak.
- [x] Çok satırlı yeni bir satırla gerekir mi? Bence yapmalıyız. Ayrıca gelecekte
"""xmlgibi şeyleri destekleme olanağı da sunar.
Tasarım kararı: Evet, çok satırlının yeni bir satırla başlamasını gerektiriyoruz.
- [x] Otomatik girintisizleştirme hiç yapılmalı mı? Bence yapmalıyız. Kodun çok daha hoş görünmesini sağlar.
Tasarım kararı: Evet, otomatik girintileme yapılacaktır.
- [x] farklı boşluk türlerini karıştırmayı ortak boşlukta kısıtlamalı mıyız? Bence bunu yapmamalıyız. Aslında, "girinti için sekme, hizalama için boşluk" olarak adlandırılan yaygın bir girintileme stratejisi vardır. Başlangıç sınırlayıcısının sekme durağında başlamadığı bir durumda bitiş sınırlayıcısını başlangıç sınırlayıcısıyla hizalamak için bunu kullanmak çok doğal olacaktır.
Tasarım kararı: Boşluk karıştırma konusunda herhangi bir kısıtlamamız olmayacaktır.
- Çitler için başka bir şey mi kullanmalıyız?
`markdown söz dizimiyle eşleşecek ve bu dizeleri her zaman üç tırnakla başlatmamız gerekmeyecek anlamına gelir. Ortak dava için sadece bir tane yeterli olur.
Tasarım kararı: """ kullanacağız
- [x] Sınırlayıcının dize değerindeki en uzun tırnak dizisinden daha fazla tırnak işaretine sahip olması gerekiyor mu? Teknik olarak gerekli değildir. mesela:
var v = """
contents"""""
"""
Bu, sınırlayıcı olarak """ olan bir dizedir. Birçok topluluk üyesi bunun kafa karıştırıcı olduğunu belirtti ve böyle bir durumda sınırlayıcının her zaman daha fazla karaktere sahip olmasını zorunlu kılmalıdır. Bu, şu şekilde olur:
var v = """"""
contents"""""
""""""
Tasarım kararı: Evet, sınırlayıcı dizenin kendisindeki tüm tırnak dizilerinden daha uzun olmalıdır.
C# feature specifications