【问题标题】:Cannot find InvalidCastException in C# Application在 C# 应用程序中找不到 InvalidCastException
【发布时间】:2015-08-23 03:49:29
【问题描述】:

我在 Visual Studio 中遇到了一个奇怪的错误,当然这个很棒的软件无法告诉我错误在哪里,只是我遇到了一个错误。我想我能做的最好的就是粘贴我的代码。

using (SQLiteCommand cmd = new SQLiteCommand(query, con))
{
    using (SQLiteDataReader rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            //Console.WriteLine("{0} ", rdr["logLnNum"]);
            ulong start, end, delta = 0;
            string contentStr;
            string contentMarkup;
            String group;

            start = (ulong)rdr["startTime"];
            end = (ulong)rdr["endTime"];
            convertTimes(start, end, 2728232, delta);

            contentStr = String.Format("{0}, {1}, {2}, {3}, {4} (ms)", 
                rdr["offsetOfData"], rdr["amountOfData"], rdr["filename"], 
                rdr["logLnNum"], (delta * .001));
            contentMarkup = "<div title=\"" + contentStr + "\">" + contentStr + "</div>";

            group = String.Format("{0:X}", rdr["threadId"]);
            group = group + ", " + rdr["threadName"];

            TimelineData inputData = new TimelineData(contentMarkup, end, group, start);
            Console.WriteLine("Data processed");
            dataSet.Add(inputData);
        }
    }
}

同样,我得到的唯一错误是 .exe 中发生“System.InvalidCastException”。

【问题讨论】:

  • 异常发生在哪一行?你有 2 个(ulong)演员表,可能是这个
  • 是的,直接从 DataReader 项进行投射是行不通的。只是为了测试,尝试用start = ulong.Parse(rdr["startTime"].ToString())替换(即)start = (ulong)rdr["startTime"];
  • @DenisYarkovoy 好问题,但正如我解释的那样,它不会告诉我台词。它只是说它正在发生,仅此而已。
  • @helrich 请作为答案发布,以便我将其标记为正确。它奏效了。

标签: c# winforms visual-studio visual-studio-2012 webforms


【解决方案1】:

仅当该对象从您要转换为的类型继承时(无论如何),从对象直接转换才有效。

DataReader 中获取所需类型的简单方法是调用

[type].Parse(reader[index].ToString())

[type] 是你想要转换的地方,即

ulong.Parse(rdr["startTime"].ToString())

DataReader 对象通常具有.GetInt32(int).GetDecimal(int) 等,只需要您传入要解析的列的索引。如果只有列名,可以使用Reader.GetOrdinal("yourColumnName")

【讨论】:

    【解决方案2】:

    我想建议您使用一种额外的方法来界定这种错误。 例如,考虑以下代码:

    protected T getDataValue<T>(object value)
    {
            if (value != null && DBNull.Value != value)
                return (T)value;
            else
                return default(T);
    }
    

    然后在数据读取器迭代中为检索到的每个值调用它,这将帮助您在调试期间检测哪个字段产生异常。 示例:

    start = getDataValue<ulong>(rdr["startTime"]);
    end = getDataValue<ulong>(rdr["endTime"]);
    

    简而言之,在处理数据访问以避免异常时,我通常遵循以下准则:

    • 如果您有权访问数据库,请在从 ADO 执行查询之前使用 db 客户端检查您的数据,这可以通过执行相同的查询来完成。

    • 考虑在两个层(DB 和 App)中使用相同的类型,以避免转换异常 --> 从 varchar 转换为 int 与从 int 到 int 的简单转换(当然它是作为一个对象来的,但它肯定有一个类型期望值),你在使用相同类型时减少了很多验证逻辑。

    • 如果您的表的字段接受空值,请考虑使用转换策略(如我给您的方法)在空值时分配一个有效值。

    • 尽量避免在 DataAccess 方法中写太多“逻辑”,保持简单,您可以使用 DTO 或业务类来存储您从 db 获得的所有值,然后使用它/修改/在业务层创建逻辑。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2019-03-10
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      • 2020-04-26
      • 2021-05-04
      • 1970-01-01
      相关资源
      最近更新 更多