【发布时间】:2018-01-20 04:37:20
【问题描述】:
感谢您的帮助。我已经为此苦苦挣扎了太久了。
我可以通过使用重复的属性列表创建两个单独的模型类来轻松解决这个问题,但我想了解如何使用基类来实现这一点。所以,IntSensor 和 ExtSensor 都是 Sensor。从另一个类中,我解析了一个包含所有数据的 json 文件,效果很好。但是,尝试调用返回 List<Sensor> 基类的方法并尝试将其转换为任一子类正在杀死我。我做错了什么......还是有更好的方法?谢谢!
PS:这可能看起来像一个重复的问题,但我尝试了其他解决方案,它们在代码中的“存储库类”中标记为“//在其他 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 {}
//业务类--解析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;
}
}
//存储库
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;
}
}
【问题讨论】:
-
您遇到了“泛型类型差异”。
List<IntSensor>与List<Sensor>根本不兼容。例如,给定一个List<Sensor>,您可以将ExtSensor放入其中。然后,如果您被允许强制转换为List<IntSensor>,那么现在您将得到一个应该只有IntSensor元素但有一个ExtSensor元素的列表。 -
请注意,就您的代码中的三个尝试而言:您无法转换您拥有的对象。
Cast<T>()会抛出异常,OfType<T>()不会返回任何东西。你可以使用ConvertAll(),但是你的lambda需要创建新对象,而不是尝试从Sensor转换为例如IntSensor。有关您问题的这方面的信息,请参阅第二个标记的副本。 -
我不同意这是一个重复的问题。尝试其他帖子中的任何解决方案。我不认为他们工作。一个答案是 list
.Type of ... 不起作用。其他答案也不起作用。用“重复”的答案回答这些主题很容易,但要确保这些重复的答案首先起作用。我可能错了,但我不这么认为。不过感谢您的回复。 -
此外,这不是继承的基础:ExternalSensor“是”传感器,InternalSensor“是”传感器吗?我认为我可以将其转换为派生类型?
-
另一个答案“不起作用”只是在您没有正确应用它们的意义上。您的问题的基础假设您正在创建
Sensor对象。问题中没有任何内容表明您可以首先创建不同类型的对象;您是专门询问有关演员表的问题。 “这不是继承的基础” - 不,不是您尝试使用它的方式。继承意味着派生类的实例“是”基类的实例;但它不是一条双向街道。
标签: c# asp.net-web-api