我试图编写一个Linq(到Objects)查询,将结果强制转换为接口,如下所示:
var data = (from row in CicApplication.Vaporizer473Cache
where row.Coater == coater
select row).Cast<IVaporizerData>();
这似乎是唯一的方法,因为我无法在select中创建接口的实例。我有两个问题:
演员如何实际完成?它是否会在源中找到每个属性并将其值复制到具有相同名称的interface属性?
我的界面中有一个属性,它不包含在源代码中,但我想以某种方式在此操作中设置其值。这可能吗?或者在查询之后我需要在每个语句中执行此操作吗?
如果有帮助,数据源的类定义(Vaporizer473Cache)如下所示。界面非常相似。
internal class Vaporizer473
{
/// <summary>
/// Gets or sets the Coater property
/// </summary>
public string Coater { get; set; }
/// <summary>
/// Gets or sets the CoaterTime property
/// </summary>
public DateTime? CoaterTime { get; set; }
/// <summary>
/// Gets or sets the TemperatureLeftTubeA property
/// </summary>
public double? TemperatureLeftTubeA { get; set; }
/// <summary>
/// Gets or sets the TemperatureLeftTubeB property
/// </summary>
public double? TemperatureLeftTubeB { get; set; }
/// <summary>
/// Gets or sets the TemperatureRightTubeA property
/// </summary>
public double? TemperatureRightTubeA { get; set; }
/// <summary>
/// Gets or sets the TemperatureRightTubeB property
/// </summary>
public double? TemperatureRightTubeB { get; set; }
}
答案 0 :(得分:4)
即使编译器不会抱怨您提供的语法,它也不会运行。您无法将对象强制转换为未实现的接口。
Cast方法只是一种方便的方法,它尝试将给定IEnumerable
中的每个对象强制转换为您提供的泛型类型。如果Vaporizer473 实施IVaporizerData
,那么您可以轻松地说:
var data = from row in CicApplication.Vaporizer473Cache
where row.Coater == coater
select (IVaporizerData)row;
其次:
我的界面中有一个未包含在源代码中的属性,但我想在此操作期间以某种方式设置其值。这可能吗?或者在查询之后我需要在每个语句中执行此操作吗?
正如您现在已经想到的那样,您的课程必须在您的界面中实现该属性。 (你可以这样做explicitly所以它不会在你的实际类实现上使用intellisense等等。)可能通过使用复杂{{1}来设置值委托,但它不是LINQ的用途,我会高度劝阻它。这是一个Select
循环是适当的事情。
请记住,如果您修改来自缓存的项目,您将修改原始对象而不是它们的克隆。这可能会产生深远的影响。您可能希望创建新对象来代表您正在寻找的数据。
答案 1 :(得分:1)
很简单。 将对象转换为另一种类型并不意味着创建了另一个对象。这是同一个对象的不同“视图”。您的类必须实现接口才能执行此操作。因此,强制转换意味着相同的对象仍然在可枚举中。
由于在转换对象时未创建新对象,因此无法设置接口的额外属性的值。但这也意味着你已经在对象中拥有了属性,因为你的对象正在实现接口。
答案 2 :(得分:1)
回答你的第一个问题,是的,这就是它的完成方式。但是,查看代码时,Vaporizer473
类似乎没有实现IVaporizorData
。假设这只是一个疏忽?如果没有,您将需要实现该接口,以便Cast<>()
调用工作。
关于你的第二个问题,是的,你可以在之后的每个块中设置它,或者你可以使用Select
来设置属性并进行强制转换,如下所示:
CicApplication.Vaporizer473Cache
.Where( r => r.Coater = coater)
.Select((r) => {
r.SomeProperty = somevalue;
return r as IVaporizerData
});