Letterlijke tekenreeks met meerdere regels in C#

Is er een gemakkelijke manier om een ​​letterlijke tekenreeks met meerdere regels in C# te maken?

Dit is wat ik nu heb:

string query = "SELECT foo, bar"
+ " FROM table"
+ " WHERE id = 42";

Ik weet dat PHP heeft

<<<BLOCK
BLOCK;

Heeft C# iets soortgelijks?


Antwoord 1, autoriteit 100%

Je kunt het @ symbool voor een string gebruiken om een ​​verbatim letterlijke tekenreeks:

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

Ook hoeft u geen speciale tekens te escapen wanneer u deze methode gebruikt, behalve dubbele aanhalingstekens zoals weergegeven in het antwoord van Jon Skeet.


Antwoord 2, autoriteit 34%

Het heet een verbatim letterlijke tekenreeks in C#, en het is gewoon een kwestie van @ voor de letterlijke tekst zetten. Dit staat niet alleen meerdere lijnen toe, maar schakelt ook ontsnappen uit. U kunt dus bijvoorbeeld het volgende doen:

string query = @"SELECT foo, bar
FROM table
WHERE name = 'a\b'";

Dit omvat echter ook de regeleinden (met welke regeleinde uw bron ze ook heeft) in de tekenreeks. Voor SQL is dat niet alleen ongevaarlijk, maar verbetert het waarschijnlijk ook de leesbaarheid overal waar u de tekenreeks ziet – maar op andere plaatsen is het misschien niet vereist, in welk geval u ofwel geen meerregelige regel hoeft te gebruiken letterlijke tekenreeks om mee te beginnen, of verwijder ze uit de resulterende tekenreeks.

Het enige ontsnappingspunt is dat als je een dubbel aanhalingsteken wilt, je een extra dubbel aanhalingsteken moet toevoegen:

string quote = @"Jon said, ""This will work,"" - and it did!";

Antwoord 3, autoriteit 8%

Als een kanttekening, met C# 6.0 kun je nu geïnterpoleerde tekenreeksen combineren met de letterlijke tekenreeks:

string camlCondition = $@"
<Where>
    <Contains>
        <FieldRef Name='Resource'/>
        <Value Type='Text'>{(string)parameter}</Value>
    </Contains>
</Where>";

Antwoord 4, autoriteit 7%

Het probleem met het gebruik van letterlijke tekenreeksen is dat het je code er een beetje “raar” uit kan laten zien, want om geen spaties in de tekenreeks zelf te krijgen, moet deze volledig links uitgelijnd zijn :

    var someString = @"The
quick
brown
fox...";

Jammer.

Dus de oplossing die ik graag gebruik, die alles mooi in lijn houdt met de rest van je code, is:

var someString = String.Join(
    Environment.NewLine,
    "The",
    "quick",
    "brown",
    "fox...");

En natuurlijk, als je regels van een SQL-instructie logisch wilt opsplitsen zoals je bent en geen nieuwe regel nodig hebt, kun je natuurlijk altijd Environment.NewLine vervangen door " ".


Antwoord 5, autoriteit 6%

Een ander punt waar je op moet letten, is het gebruik van letterlijke tekenreeksen in string.Format. In dat geval moet u accolades/haakjes ‘{‘ en ‘}’ escapen.

// this would give a format exception
string.Format(@"<script> function test(x) 
      { return x * {0} } </script>", aMagicValue)
// this contrived example would work
string.Format(@"<script> function test(x) 
      {{ return x * {0} }} </script>", aMagicValue)

Antwoord 6, autoriteit 4%

Waarom blijven mensen strings verwarren met letterlijke strings? Het geaccepteerde antwoord is een geweldig antwoord op een andere vraag; niet voor deze.

Ik weet dat dit een oud onderwerp is, maar ik kwam hier met mogelijk dezelfde vraag als de OP, en het is frustrerend om te zien hoe mensen het verkeerd blijven lezen. Of misschien lees ik het verkeerd, ik weet het niet.

Een string is ruwweg een gebied in het computergeheugen dat tijdens de uitvoering van een programma een reeks bytes bevat die aan teksttekens kunnen worden toegewezen. Een letterlijke tekenreeks daarentegen is een stuk broncode, nog niet gecompileerd, dat de waarde vertegenwoordigt die wordt gebruikt om een ​​tekenreeks later te initialiseren, tijdens de uitvoering van het programma waarin deze verschijnt.

In C#, de instructie…

 string query = "SELECT foo, bar"
 + " FROM table"
 + " WHERE id = 42";

produceert niet een string van drie regels maar een oneliner; de aaneenschakeling van drie strings (elk geïnitialiseerd vanuit een andere letterlijke) waarvan geen enkele een nieuwe regelmodifier bevat.

Wat de OP lijkt te vragen -tenminste wat ik zou vragen met die woorden- is niet hoe in de gecompileerde string regeleinden moeten worden geïntroduceerd die lijken op die in de broncode, maar hoe te breken voor verduidelijking van een lange, enkele regel tekst in de broncode zonder onderbrekingen in de gecompileerde tekenreeks te introduceren. En zonder een langere uitvoeringstijd te vereisen, besteed aan het samenvoegen van de meerdere substrings die uit de broncode komen. Zoals de achterste schuine strepen in een letterlijke tekenreeks met meerdere regels in javascript of C++.

Het gebruik van letterlijke tekenreeksen, laat staan ​​StringBuilders, String.Joins of zelfs geneste functies met tekenreeksomkeringen en wat niet, doet me denken dat mensen dat niet zijn de vraag echt begrijpen. Of misschien begrijp ik het niet.

Voor zover ik weet, heeft C# (tenminste in de paleolithische versie die ik nog steeds gebruik, van het vorige decennium) geen functie om op een schone manier multiline string literals te produceren die kunnen worden opgelost tijdens compilatie in plaats van uitvoering.

Misschien ondersteunen de huidige versies het, maar ik dacht ik deel het verschil dat ik waarneem tussen strings en letterlijke tekenreeksen.

UPDATE:

(Uit de opmerking van MeowCat2012) Dat kan. De “+” benadering van OP is de beste. Volgens de specificaties is de optimalisatie gegarandeerd: http://stackoverflow.com/a/288802/9399618


Antwoord 7

Meerdere regels toevoegen: gebruik @

string query = @"SELECT foo, bar
FROM table
WHERE id = 42";

Voeg tekenreekswaarden toe aan het midden: gebruik $

string text ="beer";
string query = $"SELECT foo {text} bar ";

Tekenreeks met meerdere regels Voeg waarden toe aan het midden: gebruik $@

string text ="Customer";
string query = $@"SELECT foo, bar
FROM {text}Table
WHERE id = 42";

Antwoord 8

U kunt @ en “” gebruiken.

        string sourse = @"{
        ""items"":[
        {
            ""itemId"":0,
            ""name"":""item0""
        },
        {
            ""itemId"":1,
            ""name"":""item1""
        }
        ]
    }";

Antwoord 9

Ik heb dit niet gezien, dus ik zal het hier posten (als je geïnteresseerd bent in het doorgeven van een string, kun je dit ook doen.) Het idee is dat je de string op meerdere regels kunt splitsen en je eigen string kunt toevoegen inhoud (ook op meerdere regels) op elke gewenste manier. Hier kan “tableName” worden doorgegeven aan de string.

    private string createTableQuery = "";
    void createTable(string tableName)
    {
         createTableQuery = @"CREATE TABLE IF NOT EXISTS
                ["+ tableName  + @"] (
               [ID] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 
               [Key] NVARCHAR(2048)  NULL, 
               [Value] VARCHAR(2048)  NULL
                                )";
    }

Antwoord 10

Ja, je kunt een string op meerdere regels splitsen zonder nieuwe regels in de eigenlijke string te introduceren, maar het is niet mooi:

string s = $@"This string{
string.Empty} contains no newlines{
string.Empty} even though it is spread onto{
string.Empty} multiple lines.";

De truc is om code te introduceren die evalueert als leeg, en die code kan nieuwe regels bevatten zonder de uitvoer te beïnvloeden. Ik heb deze aanpak van dit antwoord aangepast aan een vergelijkbare vraag.

Er is blijkbaar wat verwarring over wat de vraag is, maar er zijn twee hints dat we hier een letterlijke tekenreeks willen die geen newline-tekens bevat, waarvan de definitie meerdere regels beslaat. (in de opmerkingen zegt hij dat, en “hier is wat ik heb” toont code die geen string maakt met nieuwe regels erin)

Deze eenheidstest toont de bedoeling:

    [TestMethod]
    public void StringLiteralDoesNotContainSpaces()
    {
        string query = "hi"
                     + "there";
        Assert.AreEqual("hithere", query);
    }

Verander de bovenstaande definitie van query zodat het één letterlijke tekenreeks is, in plaats van de aaneenschakeling van twee tekenreeksletterwoorden die al dan niet door de compiler tot één kunnen worden geoptimaliseerd.

De C++-benadering zou zijn om elke regel te beëindigen met een backslash, waardoor het teken van de nieuwe regel een escapeteken krijgt en niet in de uitvoer verschijnt. Helaas is er dan nog steeds het probleem dat elke regel na de eerste moet worden uitgelijnd om geen extra witruimte aan het resultaat toe te voegen.

Er is maar één optie die niet afhankelijk is van compiler-optimalisaties die mogelijk niet plaatsvinden, en dat is om uw definitie op één regel te plaatsen. Als je wilt vertrouwen op compiler-optimalisaties, is de + die je al hebt geweldig; u hoeft de tekenreeks niet links uit te lijnen, u krijgt geen nieuwe regels in het resultaat en het is maar één bewerking, geen functieaanroepen, om optimalisatie te verwachten.


Antwoord 11

Als je geen spaties/nieuwe regels wilt, lijkt het toevoegen van strings te werken:

var myString = String.Format(
  "hello " + 
  "world" +
  " i am {0}" +
  " and I like {1}.",
  animalType,
  animalPreferenceType
);
// hello world i am a pony and I like other ponies.

Je kunt het bovenstaande hier uitvoeren als je wilt.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

13 − 2 =

Other episodes