Exercício – Refatorar e melhorar seções de código usando as ferramentas do GitHub Copilot
O GitHub Copilot pode ajudar você a atualizar seu código sugerindo alterações que aprimorem a qualidade, a confiabilidade, o desempenho e a segurança do código.
Neste exercício, você usará o GitHub Copilot para refatorar e aprimorar as seguintes seções do código:
Você refatora a classe EnumHelper para usar dicionários em vez de reflexão. O uso de dicionários melhora o desempenho reduzindo a sobrecarga de reflexão. Eliminar a reflexão também melhora a legibilidade, a manutenção e a segurança do código.
Você refatora os métodos de acesso a dados para usar a LINQ (Consulta Integrada à Linguagem) em vez de loops foreach. O uso da LINQ fornece uma maneira mais concisa e legível de consultar coleções, bancos de dados e documentos XML. O uso da LINQ pode melhorar a legibilidade, manutenção e desempenho do código.
Usar o GitHub Copilot para refatorar a classe EnumHelper
Reflexão é um recurso poderoso que permite inspecionar e manipular objetos em runtime. No entanto, a reflexão pode ser lenta e há possíveis riscos de segurança associados à reflexão que devem ser considerados.
A classe EnumHelper existente usa reflexão para recuperar o atributo de descrição de um valor de enumeração. Você pode refatorar a classe EnumHelper para usar dicionários em vez de reflexão. O uso de dicionários pode melhorar o desempenho e eliminar qualquer preocupação de segurança associada ao uso de reflexão.
Neste exercício, você usará o GitHub Copilot para refatorar a classe EnumHelper.
Use as seguintes etapas para concluir esta seção do exercício:
Use a exibição do Gerenciador de Soluções para abrir o arquivo EnumHelper.cs.
using System.ComponentModel; using System.Reflection; namespace Library.ApplicationCore.Enums; public static class EnumHelper { public static string GetDescription(Enum value) { if (value == null) return string.Empty; FieldInfo fieldInfo = value.GetType().GetField(value.ToString())!; DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) { return attributes[0].Description; } else { return value.ToString(); } } }Abra o modo de exibição de Chat e adicione os seguintes arquivos ao contexto do Chat:
EnumHelper.cs,LoanExtensionStatus.cs,LoanReturnStatus.cs,MembershipRenewalStatus.cs.Digite a seguinte solicitação:
@workspace I want to refactor the `EnumHelper` class using dictionaries rather than reflection to get enum description attributes. I want a separate dictionary for each enum. The enum values are in the `LoanExtensionStatus.cs`, `LoanReturnStatus.cs`, and `MembershipRenewalStatus.cs` files. Explain how to update the EnumHelper class to use dictionaries and provide the updated code.Esta solicitação pede que o GitHub Copilot forneça uma explicação de como atualizar a classe EnumHelper para usar dicionários em vez de reflexão. Ele também solicita o código atualizado que usa dicionários para cada valor de enumeração.
Reserve um minuto para examinar a explicação fornecida pelo GitHub Copilot.
A explicação deve ser semelhante à seguinte descrição:
To refactor the `EnumHelper` class to use dictionaries for each enum, you need to create a dictionary for each enum type that maps the enum values to their descriptions. This will eliminate the need for reflection at runtime. Here's how you can update the `EnumHelper` class: 1. Create dictionaries for each enum type. 2. Populate these dictionaries with the enum values and their corresponding descriptions. 3. Update the `GetDescription` method to use these dictionaries. Below is the updated code for the EnumHelper class:using System.ComponentModel; using System.Collections.Generic; namespace Library.ApplicationCore.Enums { public static class EnumHelper { private static readonly Dictionary<MembershipRenewalStatus, string> MembershipRenewalStatusDescriptions = new() { { MembershipRenewalStatus.Success, "Membership renewal was successful." }, { MembershipRenewalStatus.PatronNotFound, "Patron not found." }, { MembershipRenewalStatus.TooEarlyToRenew, "It is too early to renew the membership." }, { MembershipRenewalStatus.LoanNotReturned, "Cannot renew membership due to an outstanding loan." }, { MembershipRenewalStatus.Error, "Cannot renew membership due to an error." } }; private static readonly Dictionary<LoanReturnStatus, string> LoanReturnStatusDescriptions = new() { { LoanReturnStatus.Success, "Book was successfully returned." }, { LoanReturnStatus.LoanNotFound, "Loan not found." }, { LoanReturnStatus.AlreadyReturned, "Cannot return book as the book is already returned." }, { LoanReturnStatus.Error, "Cannot return book due to an error." } }; private static readonly Dictionary<LoanExtensionStatus, string> LoanExtensionStatusDescriptions = new() { { LoanExtensionStatus.Success, "Book loan extension was successful." }, { LoanExtensionStatus.LoanNotFound, "Loan not found." }, { LoanExtensionStatus.LoanExpired, "Cannot extend book loan as it already has expired. Return the book instead." }, { LoanExtensionStatus.MembershipExpired, "Cannot extend book loan due to expired patron's membership." }, { LoanExtensionStatus.LoanReturned, "Cannot extend book loan as the book is already returned." }, { LoanExtensionStatus.Error, "Cannot extend book loan due to an error." } }; public static string GetDescription(Enum value) { if (value == null) return string.Empty; return value switch { MembershipRenewalStatus status => MembershipRenewalStatusDescriptions[status], LoanReturnStatus status => LoanReturnStatusDescriptions[status], LoanExtensionStatus status => LoanExtensionStatusDescriptions[status], _ => value.ToString() }; } } }This refactored EnumHelper class uses dictionaries to store the descriptions for each enum type. The GetDescription method now uses pattern matching to determine the type of the enum and retrieves the description from the appropriate dictionary. This approach avoids the use of reflection and improves performance.Observação
Se o GitHub Copilot não preencher os dicionários com as descrições corretas, verifique se a extensão do GitHub Copilot não está solicitando uma reinicialização. Se estiver, reinicie a extensão e tente a solicitação novamente.
Use a classe
EnumHelpersugerida pelo GitHub Copilot para atualizar seu arquivo EnumHelper.cs.Certifique-se de que sua classe
EnumHelperatualizada esteja usando os valores de enumeração dos arquivosLoanExtensionStatus.cs,LoanReturnStatus.cseMembershipRenewalStatus.cs.Abra cada um dos arquivos de enumeração e verifique se os valores de enumeração nos dicionários estão corretos. Se houver discrepâncias, o GitHub Copilot atualizará os dicionários para cada enumeração individualmente. Por exemplo, você pode usar a seguinte solicitação para a enumeração
LoanExtensionStatus:@workspace Use the description values in LoanExtensionStatus.cs to update the LoanExtensionStatus dictionary in the EnumHelper class. Provide the updated code for the LoanExtensionStatus dictionary in the EnumHelper class.Se necessário, use a mesma abordagem para as enumerações
LoanReturnStatuseMembershipRenewalStatus.Reserve um minuto para examinar o método
GetDescription.public static string GetDescription(Enum value) { if (value == null) return string.Empty; return value switch { MembershipRenewalStatus status => MembershipRenewalStatusDescriptions[status], LoanReturnStatus status => LoanReturnStatusDescriptions[status], LoanExtensionStatus status => LoanExtensionStatusDescriptions[status], _ => value.ToString() }; }Esse código usa os padrões correspondentes para determinar o tipo da enumeração e recuperar a descrição do dicionário apropriado. A instrução
switchverifica o tipo devalueda enumeração e retorna a descrição correspondente do dicionário. Se o valor da enumeração não for encontrado no dicionário, o método retornará o valor de enumeração como uma cadeia de caracteres.Se você pedir ao GitHub Copilot para refatorar esse código e eliminar as expressões lambda, fica mais fácil ler:
public static string GetDescription(Enum value) { if (value == null) return string.Empty; switch (value) { case MembershipRenewalStatus status: return MembershipRenewalStatusDescriptions[status]; case LoanReturnStatus status: return LoanReturnStatusDescriptions[status]; case LoanExtensionStatus status: return LoanExtensionStatusDescriptions[status]; default: return value.ToString(); } }Crie sua solução para garantir que não haja erros.
Você verá avisos. Você pode ignorá-los por enquanto.
Atualizar os métodos de acesso aos dados para usar LINQ
LINQ (Consulta Integrada à Linguagem) é um recurso avançado em C# que permite consultar coleções, bancos de dados e documentos XML de maneira uniforme. A LINQ fornece uma maneira mais concisa e legível de consultar dados em comparação com loops foreach tradicionais.
Esta seção do exercício inclui as seguintes tarefas:
- Refatorar os métodos em JsonData.cs para usar LINQ.
- Refatorar os métodos em JsonLoanRepository.cs para usar LINQ.
- Refatorar os métodos em JsonPatronRepository.cs para usar LINQ.
Refatorar os métodos em JsonData.cs para usar LINQ
A classe JsonData inclui os seguintes métodos de acesso aos dados: GetPopulatedPatron, GetPopulatedLoan, GetPopulatedBookItem e GetPopulatedBook. Esses métodos usam loops foreach para iterar em coleções e preencher objetos. Você pode refatorar esses métodos para usar LINQ para melhorar a legibilidade e a manutenção do código.
Use as seguintes etapas para concluir esta seção do exercício:
Abra o arquivo JsonData.cs.
Selecione o método
GetPopulatedPatron.O método
GetPopulatedPatronfoi projetado para criar um objetoPatrontotalmente preenchido. Ele copia as propriedades básicas dePatrone preenche sua coleção deLoanscom objetosLoandetalhados.public Patron GetPopulatedPatron(Patron p) { Patron populated = new Patron { Id = p.Id, Name = p.Name, ImageName = p.ImageName, MembershipStart = p.MembershipStart, MembershipEnd = p.MembershipEnd, Loans = new List<Loan>() }; foreach (Loan loan in Loans!) { if (loan.PatronId == p.Id) { populated.Loans.Add(GetPopulatedLoan(loan)); } } return populated; }Abra um chat embutido e insira uma solicitação que refatore o método usando LINQ.
#selection refactor selection to `return new Patron` using LINQReserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public Patron GetPopulatedPatron(Patron p) { return new Patron { Id = p.Id, Name = p.Name, ImageName = p.ImageName, MembershipStart = p.MembershipStart, MembershipEnd = p.MembershipEnd, Loans = Loans! .Where(loan => loan.PatronId == p.Id) .Select(GetPopulatedLoan) .ToList() }; }Primeiro, uma consulta LINQ é usada para substituir o loop
foreach (Loan loan in Loans!). Com o código LINQ implementado, você pode usar um inicializador de objeto para atribuir propriedades de objeto ao novo objetoPatron. Isso alivia a necessidade de uma instânciapopulatedseparada do objetoPatron. No geral, o código atualizado é mais curto e mais legível.O código usa o leitor de entrada
ppara atribuir algumas propriedades básicas ao novo objetoPatron. Em seguida, preenche a coleçãoLoanscom empréstimos associados ao Leitor de entrada, transformando cada empréstimo usando o métodoGetPopulatedLoan.Você pode dividir a linha de código LINQ que preenche a coleção
Loans:-
Loans!: A expressãoLoans!acessa a coleçãoLoans. O operador!é um operador que permite valor nulo, indicando que o desenvolvedor está confiante de queLoansnão é nulo. Você deve garantir queLoansseja inicializado corretamente antes de chamar o métodoGetPopulatedPatron. -
.Where(loan => loan.PatronId == p.Id): Esse código filtra os empréstimos para incluir somente aqueles que pertencem ao leitor de entradap. -
.Select(GetPopulatedLoan): Esse código transforma cada empréstimo filtrado usando o métodoGetPopulatedLoan. -
.ToList(): Converte o resultado em umList<Loan>.
-
Para aceitar a atualização sugerida, selecione Aceitar.
Agora que você viu como refatorar o método
GetPopulatedPatron, pode refatorar os métodosGetPopulatedLoan,GetPopulatedBookItemeGetPopulatedBookpara usar LINQ também.Refatore os métodos
GetPopulatedLoan,GetPopulatedBookItemeGetPopulatedBookusando a mesma abordagem.Por exemplo, use as seguintes solicitações para refatorar os três métodos:
Para o método
GetPopulatedLoan:#selection refactor selection to `return new Loan` using LINQ. Use `GetPopulatedBookItem` for the `BookItem` property. Use `Single` for BookItem and Patron properties.Para o método
GetPopulatedBookItem:#selection refactor selection to `return new BookItem` using LINQ. Use `GetPopulatedBook` and `Single` for the `BookItem` property.Para o método
GetPopulatedBook:#selection refactor selection to `return new Book` using LINQ. Use `Where` and `Select` for `Author` property. Use `First` author.Depois de aceitar as atualizações sugeridas, reserve um minuto para examinar as alterações de código.
Seu código atualizado deverá ser semelhante ao seguinte código:
public Loan GetPopulatedLoan(Loan l) { return new Loan { Id = l.Id, BookItemId = l.BookItemId, PatronId = l.PatronId, LoanDate = l.LoanDate, DueDate = l.DueDate, ReturnDate = l.ReturnDate, BookItem = GetPopulatedBookItem(BookItems!.Single(bi => bi.Id == l.BookItemId)), Patron = Patrons!.Single(p => p.Id == l.PatronId) }; } public BookItem GetPopulatedBookItem(BookItem bi) { return new BookItem { Id = bi.Id, BookId = bi.BookId, AcquisitionDate = bi.AcquisitionDate, Condition = bi.Condition, Book = GetPopulatedBook(Books!.Single(b => b.Id == bi.BookId)) }; } public Book GetPopulatedBook(Book b) { return new Book { Id = b.Id, Title = b.Title, AuthorId = b.AuthorId, Genre = b.Genre, ISBN = b.ISBN, ImageName = b.ImageName, Author = Authors!.Where(a => a.Id == b.AuthorId).Select(a => new Author { Id = a.Id, Name = a.Name }).First() }; }Use a ação inteligente Explicar para ver uma explicação das consultas LINQ.
A ação inteligente Explicar fornece uma explicação detalhada das consultas LINQ usadas no código.
Por exemplo, você pode usar a ação inteligente Explicar no método
GetPopulatedBookpara ver uma explicação da consulta LINQ usada para preencher a propriedadeAuthordo objetoBook.Author = Authors!.Where(a => a.Id == b.AuthorId).Select(a => new Author { Id = a.Id, Name = a.Name }).First()A ação inteligente Explicar fornece uma explicação detalhada da consulta LINQ usada para preencher a propriedade
Authordo objetoBook.Por exemplo, a explicação pode ser semelhante a:
The active selection is a C# code snippet that assigns a value to the Author property. This value is derived from a collection of Author objects named Authors. The code uses LINQ (Language Integrated Query) to filter and transform the data within this collection. First, the Authors! expression uses the null-forgiving operator (!) to indicate that Authors is not null, even if the compiler might think otherwise. This is a way to suppress nullable warnings. The Where method is then called on the Authors collection to filter the elements. The lambda expression a => a.Id == b.AuthorId is used to find all Author objects where the Id matches the AuthorId property of another object b. After filtering, the Select method is used to project each filtered Author object into a new Author object. This is done by creating a new instance of the Author class and copying the Id and Name properties from the original Author object. Finally, the First method is called to retrieve the first element from the resulting sequence. This means that the Author property will be assigned the first Author object that matches the filter criteria and has been projected into a new Author instance. This approach ensures that the Author property is set to a new Author object with the same Id and Name as the first matching Author in the Authors collection.Crie sua solução para garantir que não haja erros.
Você verá avisos. Você pode ignorá-los por enquanto.
Refatorar os métodos em JsonLoanRepository.cs para usar LINQ
A classe JsonLoanRepository inclui os métodos de acesso aos dados GetLoan e UpdateLoan. Você refatora esses dois métodos, substituindo loops foreach por LINQ para melhorar a legibilidade e a manutenção do código.
Use as seguintes etapas para concluir esta seção do exercício:
Abra o arquivo
JsonLoanRepository.cs.Selecione o método
GetLoan.O método
GetLoanfoi projetado para recuperar um empréstimo por sua ID.public async Task<Loan?> GetLoan(int id) { await _jsonData.EnsureDataLoaded(); foreach (Loan loan in _jsonData.Loans!) { if (loan.Id == id) { Loan populated = _jsonData.GetPopulatedLoan(loan); return populated; } } return null; }Abra o chat embutido e insira uma solicitação que refatore o método usando LINQ.
Por exemplo, insira a solicitação a seguir:
#selection refactor selection using LINQ with `_jsonData.Loans!. Use `Where`, `Select` and `GetPopulatedLoan` to return `FirstOrDefault`.Reserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public async Task<Loan?> GetLoan(int id) { await _jsonData.EnsureDataLoaded(); Loan? loan = _jsonData.Loans! .Where(l => l.Id == id) .Select(l => _jsonData.GetPopulatedLoan(l)) .FirstOrDefault(); return loan; }O código atualizado usa LINQ para filtrar a coleção de empréstimos para incluir apenas o empréstimo com a ID especificada. Observe que
loandeve ser declarado como anulável (Loan? loan). Em seguida, transforma o empréstimo usando o métodoGetPopulatedLoane retorna o primeiro resultado. Se nenhum empréstimo correspondente for encontrado,FirstOrDefaultretornaránull. Depois, o método retorna esse objeto loan, que pode ser nulo se não houver nenhum empréstimo com oidespecificado. Essa abordagem garante que o empréstimo retornado seja totalmente preenchido com todos os dados relacionados necessários, fornecendo uma visão abrangente do registro de empréstimo.Esse código pode ser simplificado ainda mais:
public async Task<Loan?> GetLoan(int id) { await _jsonData.EnsureDataLoaded(); return _jsonData.Loans! .Where(l => l.Id == id) .Select(l => _jsonData.GetPopulatedLoan(l)) .FirstOrDefault(); }Para aceitar o método GetLoan atualizado, selecione Aceitar.
Selecione o método
UpdateLoan.public async Task UpdateLoan(Loan loan) { Loan? existingLoan = null; foreach (Loan l in _jsonData.Loans!) { if (l.Id == loan.Id) { existingLoan = l; break; } } if (existingLoan != null) { existingLoan.BookItemId = loan.BookItemId; existingLoan.PatronId = loan.PatronId; existingLoan.LoanDate = loan.LoanDate; existingLoan.DueDate = loan.DueDate; existingLoan.ReturnDate = loan.ReturnDate; await _jsonData.SaveLoans(_jsonData.Loans!); await _jsonData.LoadData(); } }Abra o chat embutido e insira uma solicitação que refatore o método usando LINQ.
Por exemplo, insira a solicitação a seguir:
#selection refactor selection using LINQ find an existing loan `_jsonData.Loans!. Replace existing loan.Reserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public async Task UpdateLoan(Loan loan) { Loan? existingLoan = _jsonData.Loans!.FirstOrDefault(l => l.Id == loan.Id); if (existingLoan != null) { existingLoan.BookItemId = loan.BookItemId; existingLoan.PatronId = loan.PatronId; existingLoan.LoanDate = loan.LoanDate; existingLoan.DueDate = loan.DueDate; existingLoan.ReturnDate = loan.ReturnDate; await _jsonData.SaveLoans(_jsonData.Loans!); await _jsonData.LoadData(); } }O código atualizado usa LINQ para encontrar o empréstimo existente na coleção de empréstimos. Em seguida, atualiza o empréstimo existente com os novos dados de empréstimo. Em seguida, o método salva a coleção de empréstimos atualizada e recarrega os dados. Essa abordagem garante que os dados do empréstimo sejam atualizados corretamente e que as alterações sejam mantidas no armazenamento de dados.
Você também pode adicionar o código para garantir que os dados sejam carregados antes que o método seja executado:
public async Task UpdateLoan(Loan loan) { await _jsonData.EnsureDataLoaded(); Loan? existingLoan = _jsonData.Loans!.FirstOrDefault(l => l.Id == loan.Id); if (existingLoan != null) { existingLoan.BookItemId = loan.BookItemId; existingLoan.PatronId = loan.PatronId; existingLoan.LoanDate = loan.LoanDate; existingLoan.DueDate = loan.DueDate; existingLoan.ReturnDate = loan.ReturnDate; await _jsonData.SaveLoans(_jsonData.Loans!); await _jsonData.LoadData(); } }Para aceitar o método UpdateLoan atualizado, selecione Aceitar.
Crie sua solução para garantir que não haja erros.
Você verá avisos. Você pode ignorá-los por enquanto.
Refatorar os métodos em JsonPatronRepository para usar LINQ
A classe JsonPatronRepository inclui os métodos SearchPatrons, GetPatron e UpdatePatron, e é um ótimo candidato à otimização. Você refatora esses métodos, substituindo loops foreach por LINQ para melhorar a legibilidade e a manutenção do código.
Use as seguintes etapas para concluir esta seção do exercício:
Abra o arquivo
JsonPatronRepository.cs.Selecione o método
SearchPatrons.O método
SearchPatronsfoi projetado para procurar leitores por nome.public async Task<List<Patron>> SearchPatrons(string searchInput) { await _jsonData.EnsureDataLoaded(); List<Patron> searchResults = new List<Patron>(); foreach (Patron patron in _jsonData.Patrons) { if (patron.Name.Contains(searchInput)) { searchResults.Add(patron); } } searchResults.Sort((p1, p2) => String.Compare(p1.Name, p2.Name)); searchResults = _jsonData.GetPopulatedPatrons(searchResults); return searchResults; }Abra o chat embutido e insira uma solicitação que refatore o método usando LINQ.
Por exemplo, insira a solicitação a seguir:
#selection refactor selection using LINQ with `_jsonData.Patrons!. Replace the loop with `Where`, `OrderBy`, and `GetPopulatedPatrons`.Reserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public async Task<List<Patron>> SearchPatrons(string searchInput) { await _jsonData.EnsureDataLoaded(); List<Patron> searchResults = _jsonData.Patrons! .Where(patron => patron.Name.Contains(searchInput)) .OrderBy(patron => patron.Name) .ToList(); searchResults = _jsonData.GetPopulatedPatrons(searchResults); return searchResults; }Para aceitar o método SearchPatrons atualizado, selecione Aceitar.
Selecione o método
GetPatron.O método
GetPatronfoi projetado para retornar o leitor que corresponde aoidespecificado.public async Task<Patron?> GetPatron(int id) { await _jsonData.EnsureDataLoaded(); foreach (Patron patron in _jsonData.Patrons!) { if (patron.Id == id) { Patron populated = _jsonData.GetPopulatedPatron(patron); return populated; } } return null; }Abra o chat embutido e insira uma solicitação que refatore o método usando LINQ.
Por exemplo, insira a solicitação a seguir:
#selection refactor selection using LINQ with `_jsonData.Patrons!. Use `Where`, `Select` and `GetPopulatedPatron` to return `FirstOrDefault`Reserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public async Task<Patron?> GetPatron(int id) { await _jsonData.EnsureDataLoaded(); var patron = _jsonData.Patrons! .Where(p => p.Id == id) .Select(p => _jsonData.GetPopulatedPatron(p)) .FirstOrDefault(); return patron; }Esse código pode ser simplificado ainda mais:
public async Task<Patron?> GetPatron(int id) { await _jsonData.EnsureDataLoaded(); return _jsonData.Patrons! .Where(p => p.Id == id) .Select(p => _jsonData.GetPopulatedPatron(p)) .FirstOrDefault(); }Para aceitar o método GetPatron atualizado, selecione Aceitar.
Selecione o método
UpdatePatron.O método
UpdatePatronfoi projetado para atualizar o leitor com oidespecificado.public async Task UpdatePatron(Patron patron) { await _jsonData.EnsureDataLoaded(); var patrons = _jsonData.Patrons!; Patron existingPatron = null; foreach (var p in patrons) { if (p.Id == patron.Id) { existingPatron = p; break; } } if (existingPatron != null) { existingPatron.Name = patron.Name; existingPatron.ImageName = patron.ImageName; existingPatron.MembershipStart = patron.MembershipStart; existingPatron.MembershipEnd = patron.MembershipEnd; existingPatron.Loans = patron.Loans; await _jsonData.SavePatrons(patrons); await _jsonData.LoadData(); } }Abra o chat embutido e insira uma solicitação que refatore o método usando LINQ.
Por exemplo, insira a solicitação a seguir:
#selection refactor selection using LINQ to find `patron` in `_jsonData.Patrons!. Replace existing patron with `patron`.Reserve um minuto para examinar a atualização sugerida.
A atualização sugerida será semelhante ao código a seguir:
public async Task UpdatePatron(Patron patron) { await _jsonData.EnsureDataLoaded(); var patrons = _jsonData.Patrons!; var existingPatron = patrons.FirstOrDefault(p => p.Id == patron.Id); if (existingPatron != null) { existingPatron.Name = patron.Name; existingPatron.ImageName = patron.ImageName; existingPatron.MembershipStart = patron.MembershipStart; existingPatron.MembershipEnd = patron.MembershipEnd; existingPatron.Loans = patron.Loans; await _jsonData.SavePatrons(patrons); await _jsonData.LoadData(); } }Para aceitar o método UpdatePatron atualizado, selecione Aceitar.
Verifique seu trabalho
Use as etapas a seguir para verificar seu trabalho:
Para limpar a solução, clique com o botão direito do mouse em
AccelerateAppDevGitHubCopilote selecione Limpar.Essa ação remove quaisquer artefatos de build do build anterior. A limpeza da solução redefinirá efetivamente os arquivos de dados JSON para seus valores originais durante (no diretório de saída).
Compile o aplicativo e verifique se não há erros.
Execute o aplicativo.
Você pode executar o aplicativo no modo de exibição do Gerenciador de Soluções clicando com o botão direito do mouse no projeto
Library.Console, selecionando Depuração e selecionando Iniciar Nova Instância.Quando solicitado a obter um nome de leitor, digite One e pressione Enter.
Na solicitação "Leitores Correspondentes", digite 2 e pressione Enter.
Na solicitação "Usuários Correspondentes", digite 1 e pressione Enter.
Na solicitação "Opções de Entrada", digite r e pressione Enter.
Verifique se a mensagem "Livro foi retornado com sucesso" é exibida.
Para iniciar uma nova pesquisa, digite s e pressione Enter.
Quando solicitado a obter um nome de leitor, digite One e pressione Enter.
Na solicitação "Leitores Correspondentes", digite 2 e pressione Enter.
Verifique se o primeiro empréstimo do livro está marcado como
Returned: True.Na solicitação "Opções de Entrada", digite q e, a seguir, pressione Enter.
Pare o aplicativo.