获取“无法强制转换类型为'System.Windows.Forms.DataGridViewRow'的对

本文关键字:System Forms 的对 DataGridViewRow Windows 类型 转换 获取 | 更新日期: 2023-09-27 18:36:01

我收到此错误:

"无法将类型为'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()
    };
}

现在,我已经用explicitimplicit尝试过了。两者都失败并出现相同的错误。有没有办法让Cast<ResourceModel>()工作?

注意:在 cast 运算符中放置断点时,它永远不会到达那里,所以也许我误解了Cast<>方法。

获取“无法强制转换类型为'System.Windows.Forms.DataGridViewRow'的对

您的问题的答案可以在这里找到。

为了解决你的问题,这对我来说似乎不是一个很好的"演员",而更像是一种转换

我会将您的方法更改为静态ToResourceModel扩展:

public static ResourceModel ToResourceModel(this DataGridViewRow row)
{

并将查询更改为:

var qResources = this.dataGridViewResources.Rows
    .OfType<DataGridViewRow>() 
    .Select(r => r.ToResourceModel())
    .AsQueryable();

如果您的 cast 运算符在其他地方使用,或者您出于某种原因不想更改它,您可以使用 ConvertAll

var qResources = this.dataGridViewResources
                     .Rows
                     .OfType<DataGridViewRow>() 
                     .ConvertAll<ResourceModel>(row => (ResourceModel)row)
                     .AsQueryable()

用户定义的隐式/显式转换运算符完全是编译时构造。 运行时根本不知道这些转换。 因此,Linq Cast 方法将永远无法使用这些用户定义的转换。

正在

发生的事情是,编译器会注意到您正在尝试使用需要ResourceModelDataGridViewRow 类型的变量。 它不只是不编译,而是搜索任何用户定义的转换以使其工作。 如果找到一个,它会在类型周围插入对该静态方法的调用,以根据需要对其进行转换。

因此,我们需要做的是确保在需要ResourceModel时以编译器可以看到的方式使用DataGridViewRow。 我们可以为此使用Select

var qResources = this.dataGridViewResources.Rows
    .Cast<DataGridViewRow>() 
    .Select(row => (ResourceModel)row)
    .AsQueryable();

现在,编译器可以添加对隐式转换的调用,一切都很好。

也许你可以通过首先选择绑定项目来尝试:

var qResources = this.dataGridViewResources.Rows
    .Select(r=>r.DataBoundItem)
    .Cast<ResourceModel>()
    .AsQueryable();