I’m trying to write a Linq (to Objects) query that casts the results to an interface, as shown below:
var data = (from row in CicApplication.Vaporizer473Cache
where row.Coater == coater
select row).Cast<IVaporizerData>();
This appears to be the only way to do this, because I cannot create an instance of the interface in the select. I have two questions:
-
How is the cast actually done? Will it find each property in the source and copy its value to the interface property with the same name?
-
I have a property in my interface that isn’t contained in the source, but I would like to somehow set its value during this operation. Is this possible? Or do I need to do it after the query, in a for each statement?
If it helps, the class definition for the source of the data (Vaporizer473Cache) looks as follows. The interface is very similiar.
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; }
}
Even though the compiler won’t complain with the syntax you have provided, it won’t run. You can’t cast an object to an interface that it doesn’t implement.
The Cast method is simply a convenience method that attempts to cast each object in the given
IEnumerableto the generic type you provide. If Vaporizer473 did implementIVaporizerData, then you could just as easily say:Secondly:
As you’ve figured out by now, your class will have to implement the property in your interface. (You can do this explicitly so it doesn’t crowd intellisense on your actual class implementation and such.) It is possible to set values as you go by using a complex
Selectdelegate, but it’s not what LINQ was made for, and I would highly discourage it. This is a case where aforloop is the appropriate thing to do.Bear in mind that if you modify items that come from your cache, you’ll be modifying the original objects rather than clones of them. This can have far-reaching implications. You might want to create new objects to represent the data you’re looking for instead.