C# 从基类和派生类之外的方法返回任何派生类类型
我有三个类:C# 从基类和派生类之外的方法返回任何派生类类型,c#,generics,inheritance,C#,Generics,Inheritance,我有三个类:BaseInfo,CarInfo,和PetInfo。BaseInfo类是基类CarInfo继承自BaseInfo,并具有与汽车相关的属性。最后,PetInfo还继承自BaseInfo,并具有与宠物相关的属性: public class BaseInfo { [JsonIgnore] public int UserId { get; set; } [JsonIgnore] public string UserName { get; set; } [JsonIgnor
BaseInfo
,CarInfo
,和PetInfo
。BaseInfo
类是基类CarInfo
继承自BaseInfo
,并具有与汽车相关的属性。最后,PetInfo
还继承自BaseInfo
,并具有与宠物相关的属性:
public class BaseInfo
{
[JsonIgnore]
public int UserId { get; set; }
[JsonIgnore]
public string UserName { get; set; }
[JsonIgnore]
public DateTime RegistrationDate { get; set; }
[JsonIgnore]
public DateTime LastUpdated { get; set; }
}
public class CarInfo : BaseInfo
{
[JsonPropertyName("car_make")]
public string Make { get; set; }
[JsonPropertyName("car_model")]
public string Model { get; set; }
…
}
public class PetInfo : BaseInfo
{
[JsonPropertyName("pet_breed")]
public string Breed { get; set; }
[JsonPropertyName("pet_weight")]
public long Weight { get; set; }
…
}
然后,我有一个服务,其目的是检索数据,并且在所讨论的方法中,为特定用户创建汽车或宠物列表:
public class SomeService : ISomeService
{
public List<ANY_OF_THE_DERIVED_CLASSES> GetInfoList(string type, int userId)
{
List<ANY_OF_THE_DERIVED_CLASSES> infoList = new List<ANY_OF_THE_DERIVED_CLASSES>;
switch (type)
{
case "car":
infoList = GetCarList(userId);
break;
case "pet":
infoList = GetPetList(userId);
break;
default:
break;
}
return infoList;
}
private List<CarInfo> GetCarList(int userId)
{
var carList = new List<CarInfo>();
//Logic that receives manipulates and serializes data against CarInfo and adds to list
return carList;
}
private List<PetInfo> GetPetList(int userId)
{
var petList = new List<PetInfo>();
//Logic that receives manipulates and serializes data against PetInfo and adds to list
return petList;
}
}
有没有可能让
GetInfoList
方法能够返回List
或List
?注释中@Camilo Terevinto的指导完全正确,但如果您是泛型新手,可能会给您留下一些额外的问题。为了提供一个更全面的示例,下面是您提出的代码应该是什么样子的:
ISomeService
公共接口服务
{
List GetInfoList(int userId),其中T:BaseInfo;
}
SomeService
公共类SomeService:ISomeService
{
public List GetInfoList(int userId),其中T:BaseInfo
{
列表信息列表;
开关(名称(T))
{
案例名称(CarInfo):
infoList=GetCarList(userId)作为列表;
打破
案件名称(PetInfo):
infoList=GetPetList(userId)作为列表;
打破
违约:
infoList=新列表();
打破
}
返回信息列表;
}
…
}
验证
您可以使用以下测试类来验证其是否有效:
[TestClass]
公共类服务测试
{
[测试方法]
public void GetInfoList\u ShouldReturn\u ListCarInfo()
{
var service=newsomeservice();
var list=service.GetInfoList(1);
添加(新的CarInfo());
Assert.IsNotNull(列表);
Assert.AreEqual(1,list.Count);
}
笔记
- 定义
时,需要将例如infoList
转换为列表
列表
- 您不需要将
作为参数传入,因为您可以根据type
type参数(例如通过t
)来确定nameof(t)
- 您不需要预先初始化
,因为在大多数情况下,它会立即被替换为例如infoList
的结果GetCarList()
- 如果这是一个作为可重用库的一部分的公共可用接口,那么您应该更喜欢返回
,而不是集合
()列表
- 从设计的角度来看,我不喜欢硬编码的switch语句与初始化方法有1:1的关系,但如果没有进一步了解您的业务需求,我将保持现状
public List GetInfoList(int-userId),其中T:BaseInfo=>
(T)开关的名称
{
nameof(CarInfo)=>GetCarList(userId)作为列表,
nameof(PetInfo)=>GetPetList(userId)作为列表,
_=>新列表()
};
您可能只需要一个泛型方法List GetInfoList(…)
List GetInfoList(字符串类型,int userId),其中T:BaseInfo
将是正确的泛型签名,并且添加到@CamiloTerevinto reply,只要这些类型是BaseInfo,列表将能够保存其中的任何类型(即列表可以同时保存PetInfo和CarInfo)。将方法更改为建议的public list GetInfoList(字符串类型,int userId)后其中T:BaseInfo
出现以下错误:无法将type“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.List”
和无法将type“System.Collections.Generic.List”隐式转换为“System.Collections.Generic.List”
@因此,此处缺少的部分可能需要您进行修改提供从例如列表
到列表
的转换。您可能认为这是隐式的,但事实并非如此。此外,您不需要传入字符串类型
;您可以通过例如nameof(t)获得该转换
。我在下面的完整答案中扩展了Camilo的指导,并进行了单元测试以验证功能。但是……但是……如果有人在不同的名称空间中派生另一个名为CarInfo
的类呢?如果只有两个选择,我会坚持使用if/else检查typeof……至少直到@pinkfloydx33:是的,当然是不重要的还有,谢谢你让我意识到这个建议;这是我一直想要的,尤其是在没有容器的情况下处理依赖注入。
public interface ISomeService
{
List<ANY_OF_THE_DERIVED_CLASSES> GetInfoList(string type, int userId)
}