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
看起来像这样:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using rpc.Models.Enums;
namespace rpc.DTOs.Character
{
// considered to call it GetCharacterResponseDTO.cs
public class GetCharacterDTO
{
public int Id { get; set; } = 1;
public string Name { get; set; } = "Frodo";
public string EMail{ get; set; } = "";
public int Strength { get; set; } = 10;
public int Defense { get; set; } = 10;
public int HitPoints { get; set; } = 100;
public int Intelligence { get; set; } = 10;
public RpgClass Class { get; set; } = RpgClass.Knight; // this will be and admin or user for generic usage
}
}
它使用了一个枚举(张贴在这里供参考)
using System.Text.Json.Serialization;
namespace rpc.Models.Enums
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum RpgClass
{
Knight = 1,
Mage = 2,
Cleric = 3,
NPC = 4,
Admin = 10000,
User = 9999,
}
}
相关的界面如下所示:iCharacterService.cs
:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using rpc.DTOs.Character;
using rpc.Models;
namespace rpc.Services.CharacterService
{
public interface ICharacterService
{
// other valid methods that are ok... then
// add delete character method to enforce delete functionality
// no particular errors appear here
Task<ServiceResponse<List<GetCharacterDTO>>> DeleteCharacter(int id);
}
}
实现iCharacterService.cs
(CharacterService.cs
)的相关服务如下所示。
请注意,我使用Automapper扩展(https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/)来Map模型和相应的DTO。错误发生在return语句中。
global using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using rpc.Models;
namespace rpc.Services.CharacterService
{
// enable list of characters
private static List<Character> characters = new List<Character>
{
new Character(),
new Character { Id = 2, Name = "Sam" }
};
private readonly IMapper _mapper;
public CharacterService(IMapper mapper)
{
_mapper = mapper;
}
// other valid methods here for CRU(d) actions ... they work, but the delete method
// does not work, even though its templated against similar code in this same file
// and other examples
public Task<ServiceResponse<List<GetCharacterDTO>>> DeleteCharacter(int id)
{
var serviceResponse = new ServiceResponse<List<GetCharacterDTO>>();
try
{
var character = characters.First(c => c.Id == id);
if (character is null)
{
throw new Exception($"Character with Id '{id}' not found");
}
characters.Remove(character);
serviceResponse.Data = characters.Select(c => _mapper.Map<GetCharacterDTO>(c)).ToList();
}
catch (Exception ex)
{
serviceResponse.Success = false;
serviceResponse.Message = ex.Message;
}
return serviceResponse; // VS code indicates that
// throw new NotImplementedException();
}
}
VS Code突出显示一个对话框,其中显示该行的以下信息
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
中的更新方法运行得很好,看起来像:
public async Task<ServiceResponse<GetCharacterDTO>> UpdateCharacter(UpdateCharacterDTO updatedCharacter)
{
// update all the properties with new values
var serviceResponse = new ServiceResponse<GetCharacterDTO>();
try
{
// set character to the character with the matching id
var character = characters.FirstOrDefault(c => c.Id == updatedCharacter.Id);
if (character is null)
{
//serviceResponse.Success = false;
//serviceResponse.Message = "Character not found.";
//return serviceResponse; // or throw an exception
throw new Exception($"Character with id {updatedCharacter.Id} not found.");
}
// options: use automapper to map the updatedCharacter to the character
// _mapper.Map<Character>(updatedCharacter); // or
// _mapper.Map(updatedCharacter, character); // but would have to update AutoMapperProfile.cs
// update the character with the new values
character.Name = updatedCharacter.Name;
character.EMail = updatedCharacter.EMail;
character.Class = updatedCharacter.Class;
character.Defense = updatedCharacter.Defense;
character.HitPoints = updatedCharacter.HitPoints;
character.Intelligence = updatedCharacter.Intelligence;
character.Strength = updatedCharacter.Strength;
serviceResponse.Data = _mapper.Map<GetCharacterDTO>(character);
}
catch (Exception ex)
{
serviceResponse.Success = false;
serviceResponse.Message = ex.Message;
}
return serviceResponse;
}
}
它运行良好。
任何帮助都将不胜感激。
1条答案
按热度按时间ngynwnxp1#
无法将类型System.Collections.Generic.List隐式转换为相同类型?
它们不一样,
ServiceResponse<List<GetCharacterDTO>>
不是指定为返回类型的Task<ServiceResponse<List<GetCharacterDTO>>>
。您可以使用
Task.FromResult
作为第一个代码段:async
版本的工作原理是因为它是由编译器处理的(如果你想深入了解互联网上如何以及为什么有多个资源-How Async/Await Really Works in C#,Dissecting the async methods in C#,它将完成所有必要的任务 Package 等)。但是,由于你没有做任何实际的JavaScript工作,你可以/应该把返回类型改为
ServiceResponse<List<GetCharacterDTO>>
: