以下代码有效:
List<JsonStock> stock = new List<JsonStock>();
foreach(tblStock item in repository.Single(id).tblStocks)
stock.Add((JsonStock) item);
所以你自然会认为这段代码也会起作用:
List<JsonStock> stock = repository.Single(id).tblStocks.Cast<JsonStock>().ToList()
但是我得到了错误 Invalid cast operation
- 有人知道为什么会这样吗?
UPDATE
tblStocks 是LINQ to SQL对象的列表,tblStock。
JsonStock 是tblStock类的简化版本,并作为JSON对象返回到网页。
构建以下运算符以执行转换:
public partial class tblStock{
public static explicit operator JsonStock(tblStock stock){
JsonStock item = new JsonStock
{
boxes = stock.boxes,
boxtype = stock.tblBoxType.name,
boxtype_id = stock.boxtype_id,
grade = stock.grade,
packrate = stock.packrate,
weight = stock.weight
};
return item;
}
}
Cast
用于将非泛型集合更改为通用集合,即它执行取消装箱操作。它不能以你想要的方式使用。
当你看一下执行情况 Cast
和 CastIterator
你看,它使用一个对象并将其强制转换为指定的类型:
foreach (object current in source)
{
yield return (TResult)current;
}
这只适用于 current
真的是一个 TResult
。在这种情况下,不会应用自定义转化。
这是默认行为,您可以自己测试:
double d = 0.0;
object tmp = d;
int i = (int)tmp; // throws the same exception you are getting
你想要的是一个简单的最佳实现 Select
如果 tblStocks
是一个通用的可枚举:
List<JsonStock> stock = repository.Single(id).tblStocks
.Select(x => (JsonStock)x).ToList();
或者如果 tblStocks
是一个非泛型的可枚举,你需要结合起来 Cast
和 Select
:
List<JsonStock> stock = repository.Single(id).tblStocks.Cast<tblStock>()
.Select(x => (JsonStock)x).ToList();
这将首先取消对象中的对象 tblStocks
他们的真实类型(tblStock
)然后将其转换为您想要的类型(JsonStocks
)。
隐式和显式转换运算符 被Cast忽略了。在你的情况下,这意味着
public static explicit operator JsonStock(tblStock stock)
如果被Cast忽略,则它们在foreach情况下不会被忽略
而不是使用Cast,考虑使用OfType。在Cast中,如果您正在处理的项目不是destired类型,您将获得InvalidCastException。使用OfType,它将捕获无效的强制转换并仅返回实际上是您要查找的类型的项目。
List<JsonStock> stock = repository.Single(id).tblStocks.OfType<JsonStock>().ToList()
但是如果你返回空列表,我会怀疑你的tblStocks实际上没有返回JsonStocks并且你试图将其他类型(tblStock?)投影到DTO(JsonStock)中。如果是后一种情况,则需要使用Select从基础类型投影到新类型。
List<JsonStock> stock = repository.Single(id).tblStocks
.Select(stock => new JsonStock
{
Id = stock.Id,
Val1 = stock.Val1,
Val2 = stock.Val2,
...
}
.ToList();
啊,显式运算符重载的奇迹。
因此,要解决您的问题,您可能需要事先调用Select。
List<JsonStock> stock = repository.Single(id).tblStocks.Select(x => (JsonStock)x).ToList()
但是我会说这个运算符重载是你应该摆脱的东西。考虑用类似实现的复制构造函数替换它
class JsonStock
{
public JsonStock(tblStock other)
{
// copy values here
}
}
tblStocks.Cast<JsonStock>()
执行演员表演。
(JsonStock) item
执行演员表演 或应用自定义转换。
由于tblStock是一个LINQ to SQL类,而JsonStock是由您创建的自定义类,因此没有一个是另一个的子类型。因此,你不能在两者之间施放。
要解决此问题,您可以使用 Select
LINQ的子句并手动转换元素:
List<JsonStock> stock = repository.Single(id).tblStocks
.Select(item => (JsonStock) item).ToList();