Web Services 错误CS0029无法将类型System.Collections.Generic.List隐式转换为相同类型?

wlsrxk51  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(528)

Specs:using ASP.NET Core 7.0.307,on Mac OS Ventura 13.5达尔文,VS Code 1.81.1
我在更新接口文件并在服务中使用它以便使用DTO执行删除操作后出现错误。
误差
./rpc/Services/RipterService/RipterService.cs(129,20):错误CS 0029:无法将类型“rpc.Models.ServiceResponse<System.Collections.Generic.List >”隐式转换<rpc.DTOs.Character.GetCharacterDTO>为“System.Threading.Tasks.Task<rpc.Models.ServiceResponse<System.Collections.Generic.List<rpc.DTOs.Character.GetCharacterDTO>>"[./rpc/rpc.csproj]
我注意到,我没有得到这个错误在所有与以前的CRU(D)操作(创建,读取和更新),我已经创建了这个项目。
DTO声明GetCharacterDTO看起来像这样:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using rpc.Models.Enums;
  6. namespace rpc.DTOs.Character
  7. {
  8. // considered to call it GetCharacterResponseDTO.cs
  9. public class GetCharacterDTO
  10. {
  11. public int Id { get; set; } = 1;
  12. public string Name { get; set; } = "Frodo";
  13. public string EMail{ get; set; } = "";
  14. public int Strength { get; set; } = 10;
  15. public int Defense { get; set; } = 10;
  16. public int HitPoints { get; set; } = 100;
  17. public int Intelligence { get; set; } = 10;
  18. public RpgClass Class { get; set; } = RpgClass.Knight; // this will be and admin or user for generic usage
  19. }
  20. }

它使用了一个枚举(张贴在这里供参考)

  1. using System.Text.Json.Serialization;
  2. namespace rpc.Models.Enums
  3. {
  4. [JsonConverter(typeof(JsonStringEnumConverter))]
  5. public enum RpgClass
  6. {
  7. Knight = 1,
  8. Mage = 2,
  9. Cleric = 3,
  10. NPC = 4,
  11. Admin = 10000,
  12. User = 9999,
  13. }
  14. }

相关的界面如下所示:
iCharacterService.cs

  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Threading.Tasks;
  4. using rpc.DTOs.Character;
  5. using rpc.Models;
  6. namespace rpc.Services.CharacterService
  7. {
  8. public interface ICharacterService
  9. {
  10. // other valid methods that are ok... then
  11. // add delete character method to enforce delete functionality
  12. // no particular errors appear here
  13. Task<ServiceResponse<List<GetCharacterDTO>>> DeleteCharacter(int id);
  14. }
  15. }

实现iCharacterService.csCharacterService.cs)的相关服务如下所示。
请注意,我使用Automapper扩展(https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/)来Map模型和相应的DTO。错误发生在return语句中。

  1. global using AutoMapper;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using rpc.Models;
  7. namespace rpc.Services.CharacterService
  8. {
  9. // enable list of characters
  10. private static List<Character> characters = new List<Character>
  11. {
  12. new Character(),
  13. new Character { Id = 2, Name = "Sam" }
  14. };
  15. private readonly IMapper _mapper;
  16. public CharacterService(IMapper mapper)
  17. {
  18. _mapper = mapper;
  19. }
  20. // other valid methods here for CRU(d) actions ... they work, but the delete method
  21. // does not work, even though its templated against similar code in this same file
  22. // and other examples
  23. public Task<ServiceResponse<List<GetCharacterDTO>>> DeleteCharacter(int id)
  24. {
  25. var serviceResponse = new ServiceResponse<List<GetCharacterDTO>>();
  26. try
  27. {
  28. var character = characters.First(c => c.Id == id);
  29. if (character is null)
  30. {
  31. throw new Exception($"Character with Id '{id}' not found");
  32. }
  33. characters.Remove(character);
  34. serviceResponse.Data = characters.Select(c => _mapper.Map<GetCharacterDTO>(c)).ToList();
  35. }
  36. catch (Exception ex)
  37. {
  38. serviceResponse.Success = false;
  39. serviceResponse.Message = ex.Message;
  40. }
  41. return serviceResponse; // VS code indicates that
  42. // throw new NotImplementedException();
  43. }
  44. }

VS Code突出显示一个对话框,其中显示该行的以下信息

  1. return serviceResponse

并显示此错误:
无法将类型“rpc.Models.ServiceResponse<System.Collections.Generic.List >”隐式转换<rpc.DTOs.Character.GetCharacterDTO>为“System.Threading.Tasks.Task<rpc.Models.ServiceResponse<System.Collections.Generic.List<rpc.DTOs.Character.GetCharacterDTO>>”-“RoslynCS 0029(局部变量)ServiceResponse?serviceResponse "serviceResponse”此处不为null。
不知道如何继续,我重新输入代码,从零开始,没有问题,直到返回语句。
相比之下,我在CharacterService.cs中的更新方法运行得很好,看起来像:

  1. public async Task<ServiceResponse<GetCharacterDTO>> UpdateCharacter(UpdateCharacterDTO updatedCharacter)
  2. {
  3. // update all the properties with new values
  4. var serviceResponse = new ServiceResponse<GetCharacterDTO>();
  5. try
  6. {
  7. // set character to the character with the matching id
  8. var character = characters.FirstOrDefault(c => c.Id == updatedCharacter.Id);
  9. if (character is null)
  10. {
  11. //serviceResponse.Success = false;
  12. //serviceResponse.Message = "Character not found.";
  13. //return serviceResponse; // or throw an exception
  14. throw new Exception($"Character with id {updatedCharacter.Id} not found.");
  15. }
  16. // options: use automapper to map the updatedCharacter to the character
  17. // _mapper.Map<Character>(updatedCharacter); // or
  18. // _mapper.Map(updatedCharacter, character); // but would have to update AutoMapperProfile.cs
  19. // update the character with the new values
  20. character.Name = updatedCharacter.Name;
  21. character.EMail = updatedCharacter.EMail;
  22. character.Class = updatedCharacter.Class;
  23. character.Defense = updatedCharacter.Defense;
  24. character.HitPoints = updatedCharacter.HitPoints;
  25. character.Intelligence = updatedCharacter.Intelligence;
  26. character.Strength = updatedCharacter.Strength;
  27. serviceResponse.Data = _mapper.Map<GetCharacterDTO>(character);
  28. }
  29. catch (Exception ex)
  30. {
  31. serviceResponse.Success = false;
  32. serviceResponse.Message = ex.Message;
  33. }
  34. return serviceResponse;
  35. }
  36. }

它运行良好。
任何帮助都将不胜感激。

ngynwnxp

ngynwnxp1#

无法将类型System.Collections.Generic.List隐式转换为相同类型?
它们不一样,ServiceResponse<List<GetCharacterDTO>>不是指定为返回类型的Task<ServiceResponse<List<GetCharacterDTO>>>
您可以使用Task.FromResult作为第一个代码段:

  1. return Task.FromResult(serviceResponse);

async版本的工作原理是因为它是由编译器处理的(如果你想深入了解互联网上如何以及为什么有多个资源-How Async/Await Really Works in C#Dissecting the async methods in C#,它将完成所有必要的任务 Package 等)。
但是,由于你没有做任何实际的JavaScript工作,你可以/应该把返回类型改为ServiceResponse<List<GetCharacterDTO>>

  1. public ServiceResponse<List<GetCharacterDTO>> DeleteCharacter(int id)
  2. {
  3. // ...
  4. }

相关问题