我收到此错误:
“无法将'System.Windows.Forms.DataGridViewRow'类型的对象强制转换为'Win.Models.ResourceModel'。”
执行此代码时:
var qResources = this.dataGridViewResources.Rows
.Cast<ResourceModel>()
.AsQueryable();
即使我在ResourceModel
:
public static implicit operator ResourceModel(DataGridViewRow row)
{
List<string> columns = new List<string> { "ResourceName", "Path" };
List<string> rColumns = new List<string>();
foreach (DataGridViewColumn c in row.DataGridView.Columns)
{
rColumns.Add(c.Name);
}
if (!columns.All(c => rColumns.Contains(c))) { return null; }
return new ResourceModel
{
name = row.Cells["ResourceName"].Value.AsString(),
path = row.Cells["Path"].Value.AsString()
};
}
现在,我已尝试使用explicit
AND implicit
。两者都失败了同样的错误。有没有办法让Cast<ResourceModel>()
起作用?
注意:在强制转换操作符中放置断点时,它永远不会到达那里,所以也许我误解了Cast<>
方法。
答案 0 :(得分:3)
您的问题的答案可以找到here。
为了解决你的问题,这对我来说似乎不是一个好的“演员”,而是更多的转换。
我会将您的方法更改为静态ToResourceModel
扩展名:
public static ResourceModel ToResourceModel(this DataGridViewRow row)
{
并将您的查询更改为:
var qResources = this.dataGridViewResources.Rows
.OfType<DataGridViewRow>()
.Select(r => r.ToResourceModel())
.AsQueryable();
如果您的演员在其他地方使用,或者由于某种原因您不想更改它,您可以使用ConvertAll
:
var qResources = this.dataGridViewResources
.Rows
.OfType<DataGridViewRow>()
.ConvertAll<ResourceModel>(row => (ResourceModel)row)
.AsQueryable()
答案 1 :(得分:1)
用户定义的隐式/显式转换运算符完全是编译时结构。运行时根本不了解这些转换。因此,Linq Cast
方法永远无法使用这些用户定义的转换。
正在发生的事情是编译器会注意到您正在尝试使用DataGridViewRow
类型的变量,其中ResourceModel
是预期的。它不是仅仅不编译,而是搜索任何用户定义的转换以使其工作。如果它找到一个,它会在类型周围插入对该静态方法的调用,以根据需要进行转换。
所以我们需要做的是确保在我们需要DataGridViewRow
的时候使用ResourceModel
编译器可以看到的方式。我们可以使用Select
:
var qResources = this.dataGridViewResources.Rows
.Cast<DataGridViewRow>()
.Select(row => (ResourceModel)row)
.AsQueryable();
现在编译器可以添加对隐式转换的调用,一切都很好。
答案 2 :(得分:0)
也许你可以尝试先选择绑定项目:
var qResources = this.dataGridViewResources.Rows
.Select(r=>r.DataBoundItem)
.Cast<ResourceModel>()
.AsQueryable();