Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Uma with
expressão produz uma cópia de seu operando com as propriedades e campos especificados modificados. Use a sintaxe do inicializador de objeto para especificar quais membros modificar e seus novos valores:
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 }
}
}
O operando esquerdo de uma with
expressão pode ser de um tipo de registro. Um operando esquerdo de uma with
expressão também pode ser de um tipo de estrutura ou de um tipo anônimo.
O resultado de uma with
expressão tem o mesmo tipo de tempo de execução que o operando da expressão, como mostra o exemplo a seguir:
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 }
}
}
No caso de um membro do tipo referência, somente a referência a uma instância de membro é copiada quando um operando é copiado. A cópia e o operando original têm acesso à mesma instância de tipo de referência. O exemplo a seguir demonstra esse comportamento:
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
}
}
Semântica de cópia personalizada
Qualquer tipo de classe de registro tem o construtor de cópia. Um construtor de cópia é um construtor com um único parâmetro do tipo de registro que contém. Ele copia o estado de seu argumento para uma nova instância de registro. Na avaliação de uma with
expressão, o construtor de cópia é chamado para instanciar uma nova instância de registro com base em um registro original. Depois disso, a nova instância é atualizada de acordo com as modificações especificadas. Por padrão, o construtor de cópia é implícito, ou seja, gerado pelo compilador. Se você precisar personalizar a semântica de cópia de registro, declare explicitamente um construtor de cópia com o comportamento desejado. O exemplo a seguir atualiza o exemplo anterior com um construtor de cópia explícito. O novo comportamento de cópia é copiar itens de lista em vez de uma referência de lista quando um registro é copiado:
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
}
}
Não é possível personalizar a semântica de cópia para tipos de estrutura.
Especificação da linguagem C#
Para obter mais informações, consulte as seguintes seções da observação da proposta do recurso de registros: