C#转换列表<;基类>;列出<;DerivedClass>;
谢谢你的帮助。我已经为此奋斗太久了 我可以通过创建两个具有重复属性列表的独立模型类来轻松解决这个问题,但我想学习如何使用基类实现这一点。因此,C#转换列表<;基类>;列出<;DerivedClass>;,c#,asp.net-web-api,C#,Asp.net Web Api,谢谢你的帮助。我已经为此奋斗太久了 我可以通过创建两个具有重复属性列表的独立模型类来轻松解决这个问题,但我想学习如何使用基类实现这一点。因此,IntSensor和ExtSensor都是传感器。从另一个类中,我解析了一个包含所有数据的json文件,这非常有效。但是,试图调用一个返回列表基类的方法,并试图将其转换为任何一个子类,这会让我非常痛苦。我做错了什么。。。还是有更好的办法?谢谢大家! PS:这可能看起来像是一个重复的问题,但我尝试了其他解决方案,它们在代码中的“Repository类”中标记
IntSensor
和ExtSensor
都是传感器。从另一个类中,我解析了一个包含所有数据的json文件,这非常有效。但是,试图调用一个返回列表
基类的方法,并试图将其转换为任何一个子类,这会让我非常痛苦。我做错了什么。。。还是有更好的办法?谢谢大家!
PS:这可能看起来像是一个重复的问题,但我尝试了其他解决方案,它们在代码中的“Repository类”中标记为“//在其他StackOverflow文章中看到--失败”
//模型类
public class Device
{
public string IP { get; set; }
public string Name { get; set; }
public IList<IntSensor> InternalSensors { get; set; }
public IList<ExtSensor> ExternalSensors { get; set; }
}
public class Sensor
{
public string Name { get; set; }
public string ActualTemp { get; set; }
public string HighTemp { get; set; }
public string LowTemp { get; set; }
}
public class IntSensor : Sensor {}
public class ExtSensor : Sensor {}
公共类设备
{
公共字符串IP{get;set;}
公共字符串名称{get;set;}
公共IList内部传感器{get;set;}
公共IList外部传感器{get;set;}
}
公共类传感器
{
公共字符串名称{get;set;}
公共字符串ActualTemp{get;set;}
公共字符串HighTemp{get;set;}
公共字符串LowTemp{get;set;}
}
公共类IntSensor:传感器{}
公共类ExtSensor:传感器{}
//业务类——解析json
public class ParseJsonData
{
public static RoomAlertModel GetRoomAlertModel(JObject jsonTree)
{
RoomAlertModel model = new RoomAlertModel();
model.IP = jsonTree["ip"].ToString();
model.Name = jsonTree["name"].ToString();
return model;
}
public static List<Sensor> GetSensors(JToken jToken)
{
var sensors = new List<Sensor>();
try
{
foreach (var item in jToken)
{
var s = new Sensor();
s.Label = item["lab"].ToString();
s.ActualTemp = item["tf"] != null ? item["tf"].ToString() : "";
s.HighTemp = item["hf"] != null ? item["hf"].ToString() : "";
s.LowTemp = item["lf"] != null ? item["lf"].ToString() : "";
sensors.Add(s);
}
}
catch (Exception)
{
}
return sensors;
}
}
公共类ParseJsonData
{
公共静态RoomAlertModel GetRoomAlertModel(JObject jsonTree)
{
RoomAlertModel=新的RoomAlertModel();
model.IP=jsonTree[“IP”].ToString();
model.Name=jsonTree[“Name”].ToString();
收益模型;
}
公共静态列表GetSensors(JToken JToken)
{
var传感器=新列表();
尝试
{
foreach(jToken中的var项目)
{
var s=新传感器();
s、 标签=项目[“实验室”]。ToString();
s、 ActualTemp=item[“tf”]!=null?item[“tf”]。ToString():“”;
s、 HighTemp=item[“hf”]!=null?item[“hf”]。ToString():“”;
s、 LowTemp=item[“lf”]!=null?item[“lf”]。ToString():“”;
传感器。添加(s);
}
}
捕获(例外)
{
}
返回传感器;
}
}
//存储库
public class RoomAlertRepository
{
internal RoomAlertModel Retreive()
{
var filePath = HostingEnvironment.MapPath(@"~/App_Data/RoomAlertsData.json");
var json = File.ReadAllText(filePath);
JObject jsonTree = JObject.Parse(json);
var internalSensorTree = jsonTree["internal_sen"];
var externalSensorTree = jsonTree["sensor"];
var model = ParseJsonData.GetRoomAlertModel(jsonTree);
var baseList = ParseJsonData.GetSensors(internalSensorTree);
//seen on other StackOverflow Posts -- fails
var iSensorsTry1 = baseList.Cast<IntSensor>();
//seen on other StackOverflow Posts -- fails
var iSensorsTry2 = baseList.ConvertAll(instance => (IntSensor)instance);
//seen on other StackOverflow Posts -- fails
var iSensorsTry3 = baseList.OfType<IntSensor>();
model.InternalSensor = iSensorsTry1.ToList();
return model;
}
}
公共类存储库
{
内部RoomAlertModel检索()
{
var filePath=HostingEnvironment.MapPath(@“~/App_Data/RoomAlertsData.json”);
var json=File.ReadAllText(文件路径);
JObject jsonTree=JObject.Parse(json);
var internalSensorTree=jsonTree[“internal_sen”];
var externalSensorTree=jsonTree[“传感器”];
var model=ParseJsonData.GetRoomAlertModel(jsonTree);
var baseList=ParseJsonData.GetSensors(internalSensorTree);
//在其他StackOverflow Post上看到--失败
var iSensorsTry1=baseList.Cast();
//在其他StackOverflow Post上看到--失败
var iSensorsTry2=baseList.ConvertAll(实例=>(IntSensor)实例);
//在其他StackOverflow Post上看到--失败
var iSensorsTry3=baseList.OfType();
model.InternalSensor=iSensorsTry1.ToList();
收益模型;
}
}
在GetSensors
方法中,您正在创建基类Sensor
的实例。试图隐式地将它们转换为其他派生类是不可能的。您应该在该方法中使用泛型类型参数,并创建实际派生类型的实例
类似:(注意where
子句和T
参数的new
约束)
公共静态列表GetSensors(JToken JToken),其中T:Sensor,new()
{
var传感器=新列表();
尝试
{
foreach(jToken中的var项目)
{
var s=新的T();
s、 标签=项目[“实验室”]。ToString();
s、 ActualTemp=item[“tf”]!=null?item[“tf”]。ToString():“”;
s、 HighTemp=item[“hf”]!=null?item[“hf”]。ToString():“”;
s、 LowTemp=item[“lf”]!=null?item[“lf”]。ToString():“”;
传感器。添加(s);
}
}
捕获(例外)
{
}
返回传感器;
}
现在这样称呼它:
List<IntSensor> iSensors = ParseJsonData.GetSensors<IntSensor>(internalSensorTree);
List iSensors=ParseJsonData.GetSensors(internalSensorTree);
您遇到了“通用类型差异”。列表
与列表
不兼容。例如,给定一个列表
,您可以在其中放入ExtSensor
。然后,如果您被允许强制转换到列表
,那么现在您得到了一个列表,该列表应该只包含IntSensor
元素,但有一个ExtSensor
元素。请注意,在代码中的三次尝试中,您无法强制转换您拥有的对象Cast()
将抛出异常,而类型()的将不会返回任何内容。您可以使用ConvertAll()
,但是您的lambda需要创建新对象,而不是尝试从Sensor
转换到例如IntSensor
。请参阅第二个标记为重复的问题,了解您问题的这一方面的信息。我不同意这是一个重复的问题。尝试其他帖子中的任何解决方案。我认为它们不起作用。一个答案是列表。类型是。。。不起作用。其他答案也不起作用。用“重复”答案回答这些问题很容易,但首先要确保这些重复答案有效。我可能错了,但我不这么认为。谢谢你的回复。此外,这不是继承的基础吗:ExternalSensor是一个“传感器”,InternalSensor是一个“传感器”?我认为我可以将其转换为派生类型?另一个答案“不起作用”只是在您没有正确应用它们的意义上。你问题的基础假设你是cr
List<IntSensor> iSensors = ParseJsonData.GetSensors<IntSensor>(internalSensorTree);