如何将查询结果字段分配给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
相关产品推荐
相关产品推荐

