Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De
Een with expressie maakt een kopie van de operand met de opgegeven eigenschappen en velden die zijn gewijzigd. Gebruik de syntaxis van de object-initialisatiefunctie om op te geven welke leden moeten worden gewijzigd en de nieuwe waarden:
using System;
public class WithExpressionBasicExample
{
public record NamedPoint(string Name, int X, int Y);
public static void Main()
{
var p1 = new NamedPoint("A", 0, 0);
Console.WriteLine($"{nameof(p1)}: {p1}"); // output: p1: NamedPoint { Name = A, X = 0, Y = 0 }
var p2 = p1 with { Name = "B", X = 5 };
Console.WriteLine($"{nameof(p2)}: {p2}"); // output: p2: NamedPoint { Name = B, X = 5, Y = 0 }
var p3 = p1 with
{
Name = "C",
Y = 4
};
Console.WriteLine($"{nameof(p3)}: {p3}"); // output: p3: NamedPoint { Name = C, X = 0, Y = 4 }
Console.WriteLine($"{nameof(p1)}: {p1}"); // output: p1: NamedPoint { Name = A, X = 0, Y = 0 }
var apples = new { Item = "Apples", Price = 1.19m };
Console.WriteLine($"Original: {apples}"); // output: Original: { Item = Apples, Price = 1.19 }
var saleApples = apples with { Price = 0.79m };
Console.WriteLine($"Sale: {saleApples}"); // output: Sale: { Item = Apples, Price = 0.79 }
}
}
De linkeroperand van een with expressie kan een recordtype zijn. Het kan ook een structuurtype of een anoniem type zijn.
De C#-taalreferentiedocumenten beschrijven de meest recent uitgebrachte versie van de C#-taal. Het bevat ook de eerste documentatie voor functies in openbare previews voor de aanstaande taalrelease.
De documentatie identificeert alle functies die voor het eerst zijn geïntroduceerd in de laatste drie versies van de taal of in de huidige openbare previews.
Aanbeveling
Raadpleeg het artikel over de versiegeschiedenis van de C#-taal om te achterhalen wanneer een functie voor het eerst is geïntroduceerd in C#.
Het resultaat van een with-expressie heeft hetzelfde runtimetype als de operand van de expressie, zoals in het volgende voorbeeld wordt weergegeven:
using System;
public class InheritanceExample
{
public record Point(int X, int Y);
public record NamedPoint(string Name, int X, int Y) : Point(X, Y);
public static void Main()
{
Point p1 = new NamedPoint("A", 0, 0);
Point p2 = p1 with { X = 5, Y = 3 };
Console.WriteLine(p2 is NamedPoint); // output: True
Console.WriteLine(p2); // output: NamedPoint { X = 5, Y = 3, Name = A }
}
}
Wanneer een lid een verwijzingstype is, kopieert u dat lid alleen de verwijzing naar dat lidexemplaar. Zowel de kopie als de oorspronkelijke operand hebben toegang tot hetzelfde exemplaar van het verwijzingstype. In het volgende voorbeeld ziet u dat gedrag:
using System;
using System.Collections.Generic;
public class ExampleWithReferenceType
{
public record TaggedNumber(int Number, List<string> Tags)
{
public string PrintTags() => string.Join(", ", Tags);
}
public static void Main()
{
var original = new TaggedNumber(1, new List<string> { "A", "B" });
var copy = original with { Number = 2 };
Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
// output: Tags of copy: A, B
original.Tags.Add("C");
Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
// output: Tags of copy: A, B, C
}
}
Aangepaste kopieersemantiek
Elk recordklassetype heeft een kopieerconstructor. Een kopieerconstructor is een constructor met één parameter van het bevatte recordtype. Het kopieert de toestand van zijn argument naar een nieuwe recordinstantie. Wanneer u een with expressie evalueert, wordt de kopieerconstructor aanroepen om een nieuw recordexemplaar te maken op basis van een oorspronkelijke record. Vervolgens wordt het nieuwe exemplaar bijgewerkt met de opgegeven wijzigingen. Standaardsynthetiseert de compiler de kopieerconstructor. Als u de semantiek voor het kopiëren van records wilt aanpassen, declareert u expliciet een kopieerconstructor met het gewenste gedrag. In het volgende voorbeeld wordt het voorgaande voorbeeld bijgewerkt met een expliciete kopieerconstructor. Met het nieuwe kopieergedrag worden lijstitems gekopieerd in plaats van een lijstreferentie wanneer een record wordt gekopieerd:
using System;
using System.Collections.Generic;
public class UserDefinedCopyConstructorExample
{
public record TaggedNumber(int Number, List<string> Tags)
{
protected TaggedNumber(TaggedNumber original)
{
Number = original.Number;
Tags = new List<string>(original.Tags);
}
public string PrintTags() => string.Join(", ", Tags);
}
public static void Main()
{
var original = new TaggedNumber(1, new List<string> { "A", "B" });
var copy = original with { Number = 2 };
Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
// output: Tags of copy: A, B
original.Tags.Add("C");
Console.WriteLine($"Tags of {nameof(copy)}: {copy.PrintTags()}");
// output: Tags of copy: A, B
}
}
U kunt de kopieersemantiek voor structuurtypen niet aanpassen.
Belangrijk
In de voorgaande voorbeelden zijn alle eigenschappen onafhankelijk. Geen van de eigenschappen wordt berekend op basis van andere eigenschapswaarden. Een with expressie kopieert eerst het bestaande recordexemplaren en wijzigt vervolgens alle eigenschappen of velden die zijn opgegeven in de with expressie. Berekende eigenschappen in record typen moeten worden berekend voor toegang, niet geïnitialiseerd wanneer het exemplaar wordt gemaakt. Anders kan een eigenschap de berekende waarde retourneren op basis van het oorspronkelijke exemplaar, niet de gewijzigde kopie. Zie het naslagartikel over talen voor meer informatie over record typen.
C#-taalspecificatie
Zie voor meer informatie de volgende secties van de record met voorstelnota's: