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

Error CS0029 Cannot implicitly convert type System.Collections.Generic.List to same?

提问人:DJ Eddie J 提问时间:8/14/2023 最后编辑:Guru StronDJ Eddie J 更新时间:8/14/2023 访问量:75

问:

规格:在 Mac OS Ventura 13.5 Darwin 上使用 ASP.NET Core 7.0.307,VS Code 1.81.1

更新接口文件并在服务中使用它以使用 DTO 执行删除操作后,我收到错误。

错误是

./rpc/Services/CharacterService/CharacterService.cs(129,20):错误 CS0029:无法隐式转换类型 '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.csCharacterService.cs

请注意,我正在使用 Automapper 扩展 (https://www.nuget.org/packages/AutoMapper.Extensions.Microsoft.DependencyInjection/ ) 来利用映射模型和相应的 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>>>'RoslynCS0029 (局部变量)ServiceResponse<List>?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;
    }
}

运行良好。

任何协助将不胜感激。

C# asp.net REST Web 服务 .net-core

评论

2赞 DavidG 8/14/2023
您的方法返回 a,但您没有在其中做任何工作,因此只需将其更改为 。将其作为错别字关闭Task<ServiceResponse<GetCharacterDTO>>asyncServiceResponse<GetCharacterDTO>

答:

1赞 Guru Stron 8/14/2023 #1

无法将类型 System.Collections.Generic.List 隐式转换为相同类型?

它们不相同,不是指定为返回类型的。ServiceResponse<List<GetCharacterDTO>>Task<ServiceResponse<List<GetCharacterDTO>>>

您可以用于第一个代码段:Task.FromResult

return Task.FromResult(serviceResponse); 

该版本之所以有效,是因为它是由编译器处理的(如果您想深入了解 Internet 中如何以及为什么存在多个资源,编译器将执行所有必要的任务包装等 - Async/Await 如何在 C# 中真正工作剖析 C# 中的异步方法)。async

但是,由于您没有进行任何实际的异步工作,因此您可以/应该将返回类型更改为:ServiceResponse<List<GetCharacterDTO>>

public ServiceResponse<List<GetCharacterDTO>> DeleteCharacter(int id)
{
    // ...
}

评论

0赞 DJ Eddie J 8/14/2023
谢谢!那行得通。你能为我解释一下退货声明吗?FromResult() 方法仅声明“它创建一个使用指定结果成功完成的任务”,但没有明确说明它对此删除操作上下文的含义。
0赞 Guru Stron 8/14/2023
@DJEddieJ“但不清楚它对这个删除操作上下文意味着什么”——你能详细说明一下吗?简而言之,它确实会导致任务具有状态,并且结果集为您提供的值。就类型而言,这里没有特别的魔力(与对应物相比)。new Task<TResult>(result)TaskStateFlags.RanToCompletionasync
1赞 DJ Eddie J 8/14/2023
感谢您修改后的回复,现在是有道理的,实际上只是让我头晕目眩地看了一下对象类型(忘记了任务部分,因此它看起来“相同”,需要更多的咖啡和休息)。干杯
0赞 Guru Stron 8/14/2023
@DJEddieJ发生在每个人身上!很乐意帮忙。如果答案对您有用 - 请随时将其标记为已接受;)