为什么我得到“无法转换”错误

本文关键字:转换 无法转换 错误 为什么 | 更新日期: 2023-09-27 18:06:09

我在一个新类中有以下代码:

Object[] temp_arr = new Object[5];
                temp_arr[0] = csFiles;
                temp_arr[1] = mainUrl;
                temp_arr[2] = levels;
                temp_arr[3] = currentCrawlingSite;
                temp_arr[4] = sitesToCrawl;

变量csFiles和currentCrawlingSite都是List

然后在底部我做了:

public class WebCrawlerProgressEventHandler : EventArgs
{
    public List<string> csFiles { get; set; }
    public string mainUrl { get; set; }
    public int levels { get; set; }
    public List<string> currentCrawlingSite { get; set; }
}
protected void OnProgressEvent( Object[] some_params)
{
    if (ProgressEvent != null)
        ProgressEvent(this,
                      new WebCrawlerProgressEventHandler()
                      {
                          csFiles = some_params[0],
                          mainUrl = some_params[1],
                          levels = some_params[2],
                          currentCrawlingSite = some_params[3]
                      });
}

现在我在新WebCrawlerProgressEventHandler()内的所有行上得到一个错误,每行都有相同的错误:

错误2无法隐式转换类型'object'为"System.Collections.Generic.List"。显式转换

但是,如果我删除行:public List<string> currentCrawlingSite { get; set; }和行:currentCrawlingSite = some_params[3],没有错误。

我不明白。csFilescurrentCrawlingSite都是List<string>型变量。为什么,当我添加currentCrawlingSite,我得到的错误/s?

为什么我得到“无法转换”错误

因为编译器不知道,也不可能知道Object -数组的第一个和第四个元素恰好是List<string>

你必须相应地转换它们:

csFiles = (List<String>)some_params[0]

等。如果可能的话,使用合适的类型来传递数据,而不是简单的Object -数组。

这里的要点是OnProgressEvent正在向您发送Object数组,因此您试图将Object分配给"罪魁祸首"行中的List<string>类型变量,从而隐式调用强制转换操作。你真的应该在那里做一个显式强制转换来解决你的问题。

c#中新的首选语法是:
csFiles = some_params[0] as List<String>;

currentCrawlingSiteList<string>的一个实例,some_paramsobject数组的一个实例。

不能隐式地转换这两种类型。你必须使用明确的对话。你可以像;

currentCrawlingSite = (List<string>)some_params[3];

= also

currentCrawlingSite = some_params[3] as List<string>;

您可以从Casting and Type Conversions (C# Programming Guide)

阅读更多详细信息

这是强类型保护。您应该显式地将对象强制转换为List<string>,以确保在编译时不会混淆不同的类型

csFiles = (List<string>)some_params[0]

你不会在mainUrl = some_params[1]上出现错误,因为每个对象都有ToString()方法,默认行为是调用该方法进行隐式类型转换。

J。Richter在他的书中写道:

例如,c#不需要任何特殊语法来强制转换对象到它的任何基类型,因为要考虑到基类型的强制转换安全隐式转换。然而,c#确实要求开发人员这样做将对象显式地强制转换为它的任何派生类型强制转换可能在运行时失败。

假设您要分配的数据是List,则需要将其强制转换为以下类型:

new WebCrawlerProgressEventHandler()
{
    csFiles = (List<string>)some_params[0],
    mainUrl = some_params[1],
    levels = some_params[2],
    currentCrawlingSite = (List<string>)some_params[3]
});