获取“无法将类型为'System.Windows.Forms.DataGridViewRow'的对象转换为'Win.Models.ResourceModel'。”

时间:2013-10-18 13:09:21

标签: c# .net winforms

我收到此错误:

  

“无法将'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<>方法。

3 个答案:

答案 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();