You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将查询结果字段分配给C#方法参数?

问题:C# Record组合模式下简化SkillDTO实例化写法

现有Record类定义

public record ExpertiseDTO
{
    public int Id { get; init; }
    public string Name { get; init; }
    public ExpertiseDTO(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
public record SkillDTO// : ExpertiseDTO // 已移除继承关系
{
    public ExpertiseDTO Expertise { get; init; }
    public string Potential { get; init; }
    public SkillDTO(ExpertiseDTO expertise, string potential)
        //: base(id, name)// 已移除继承构造调用
    {
        Expertise = expertise;
        Potential = potential;
    }
}

原有实例化逻辑

此前通过查询ExpertiseDTO数组创建SkillDTO数组,写法如下:

var newExpertises = new ExpertiseDTO[]
{
    new ExpertiseDTO (1, "myName"),
    new ExpertiseDTO (2, "myName1")
};
// 实际AddRange操作在IndexData类中,此处简化
ExpertiseDTO.AddRange(newExpertises);
var newSkills = new SkillDTO[]
{
    new SkillDTO (newExpertises.Where(e => e.Name == "myName").Select(e => new ExpertiseDTO(e.Id, e.Name)).FirstOrDefault(), "My first potential."),
    new SkillDTO (newExpertises.Where(e => e.Name == "myName").Select(e => new ExpertiseDTO(e.Id, e.Name)).FirstOrDefault(), "My second potential."),
    new SkillDTO (newExpertises.Where(e => e.Name == "myName1").Select(e => new ExpertiseDTO(e.Id, e.Name)).FirstOrDefault(), "My third potential.")
};
SkillDTO.AddRange(newSkills);

需求与尝试的错误写法

希望简化实例化逻辑,将查询结果的字段直接分配到方法参数位置,无需传入完整类实例或使用循环。尝试了以下写法但未成功:

new SkillDTO ((Id, Name) => newExpertises.Where(e => e.Name == "myName1").Select(e => new ExpertiseDTO(e.Id, e.Name)).FirstOrDefault(), "My third potential.")

解决方案

方案1:简化现有查询逻辑

原有代码中查询后重新new ExpertiseDTO属于冗余操作,直接复用查询到的实例即可大幅简化写法:

var newSkills = new SkillDTO[]
{
    new SkillDTO(newExpertises.FirstOrDefault(e => e.Name == "myName"), "My first potential."),
    new SkillDTO(newExpertises.FirstOrDefault(e => e.Name == "myName"), "My second potential."),
    new SkillDTO(newExpertises.FirstOrDefault(e => e.Name == "myName1"), "My third potential.")
};

方案2:通过构造函数重载直接传字段

如果确实需要直接传入Id和Name而非ExpertiseDTO实例,可以给SkillDTO新增构造函数,内部封装创建ExpertiseDTO的逻辑:

public record SkillDTO
{
    public ExpertiseDTO Expertise { get; init; }
    public string Potential { get; init; }

    // 原构造函数
    public SkillDTO(ExpertiseDTO expertise, string potential)
    {
        Expertise = expertise;
        Potential = potential;
    }

    // 新增构造函数:直接接收Id、Name和Potential
    public SkillDTO(int expertiseId, string expertiseName, string potential)
    {
        Expertise = new ExpertiseDTO(expertiseId, expertiseName);
        Potential = potential;
    }
}

此时实例化SkillDTO时可直接传入查询到的字段:

var newSkills = new SkillDTO[]
{
    new SkillDTO(newExpertises.First(e => e.Name == "myName").Id, newExpertises.First(e => e.Name == "myName").Name, "My first potential."),
    new SkillDTO(newExpertises.First(e => e.Name == "myName").Id, newExpertises.First(e => e.Name == "myName").Name, "My second potential."),
    new SkillDTO(newExpertises.First(e => e.Name == "myName1").Id, newExpertises.First(e => e.Name == "myName1").Name, "My third potential.")
};

方案3:利用Record解构特性

给ExpertiseDTO添加解构方法,实现将实例解构为Id和Name,再结合构造函数重载使用:

public record ExpertiseDTO
{
    public int Id { get; init; }
    public string Name { get; init; }
    public ExpertiseDTO(int id, string name)
    {
        Id = id;
        Name = name;
    }

    // 添加解构方法
    public void Deconstruct(out int id, out string name)
    {
        id = Id;
        name = Name;
    }
}

实例化时可先解构再传参:

var exp1 = newExpertises.First(e => e.Name == "myName");
var exp2 = newExpertises.First(e => e.Name == "myName1");

var newSkills = new SkillDTO[]
{
    new SkillDTO(exp1.Id, exp1.Name, "My first potential."),
    new SkillDTO(exp1.Id, exp1.Name, "My second potential."),
    new SkillDTO(exp2.Id, exp2.Name, "My third potential.")
};

内容的提问来源于stack exchange,提问作者Xanadu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 19:44:57