【问题标题】:InvalidCastException while casting to defined Type C#转换为定义的 C# 类型时出现 InvalidCastException
【发布时间】:2016-07-15 09:04:59
【问题描述】:

我有一个字典,其中包含字符串作为键,对象作为抽象类中的值。 我有两个派生自这个抽象类的类。

其中一个派生类运行良好,所有配置和项目均已加载和检索,没有问题。 然而,另一堂课让我很头疼。

当我尝试获取“域”类型的对象时;尽管我将值作为所述类型添加到字典中,但我得到了一个无效的强制转换异常。

代码如下:

public sealed class UserDomainConfig: ConfigParser {

    public UserDomainConfig(string configFilePath) : base(configFilePath) { }

    public Domain GetConfig(string key) => GetConfig<Domain>(key);

    public override bool LoadConfigs() {
        return base.LoadConfigs();
    }

    public UserDomainConfig SetConfig(string key, Domain value) {
        base.SetConfig(key, value);
        return this;
    }

}



public abstract class ConfigParser: IConfig {

    /* Snip */

    /// <summary>
    /// Gets the config.
    /// </summary>
    /// <returns>The config.</returns>
    /// <param name="key">Key.</param>
    /// <typeparam name="T">The 1st type parameter.</typeparam>
    public virtual T GetConfig<T>(string key) {
        object output = null;
        try {
            if (!configs.TryGetValue(key, out output))
                return default(T);
            //return (T)output;
            //return output as T;
            // This is where the exception is occurring.
            //  I've tried multiple solutions to try to remedy this issue.
            return (T)Convert.ChangeType(output, typeof(T));
        } catch (InvalidCastException ex) {
            logger.Error($"Failed to cast config { key }!");
        }
        return default(T);
    }
    /// <summary>
    /// Sets the config.
    /// </summary>
    /// <returns>The config.</returns>
    /// <param name="key">Key.</param>
    /// <param name="value">Value.</param>
    /// <typeparam name="T">The 1st type parameter.</typeparam>
    public virtual IConfig SetConfig<T>(string key, T value) {
        if (KeyExists(key))
            configs.Remove(key);
        configs.Add(key, value);
        return this;
    }

关于如何解决这个问题的任何想法,和/或为什么这首先不起作用,尽管它像字符串、布尔值和整数的魅力一样工作?

【问题讨论】:

  • 所以您要转换为Domain 对象? configs 是什么,在你尝试演员之前它给你带来了什么价值?我猜它是一个字符串或一个简单的值类型。
  • configs 是一个 Dictionary,如 OP 中所述。从 UserDomainConfig 类中可以看出,我添加了一个键/值对,其中的值是一个域对象。因此,字典中只有域对象,但是我不能从一个对象(值保存为)转换回域对象。
  • 你试过调试吗? output 变量的确切类型是什么?
  • 必须有更多内容,因为您发布的代码应该可以正常工作。
  • 只要让程序输出值的类型即可。出于某种原因,它是一个字符串?如何将对象(域)保存为以字符串为键、对象为值的字典中的字符串?如前所述,它与其他派生类完美配合,只是不适用于这个派生类。我可能最终将类型直接添加到类中,并让继承类决定字典将包含哪些类型。

标签: c# generics dictionary types casting


【解决方案1】:

Convert 类仅支持 .NET 已知的简单类型,例如 Int32StringDateTime。它不支持像Domain 这样的用户定义或复杂类型。如果您尝试将某些内容转换为不受支持的类型,Convert.ChangeType 方法将抛出 InvalidCastException。唯一的例外是,如果原始值 (output) 已经是所需的类型,它将起作用;比不需要实际的转换。

欲了解更多信息,请阅读:https://msdn.microsoft.com/en-us/library/dtb69x08(v=vs.110).aspx

如果您确定存储的值是Domain 类型,则记录更多信息。像这样的:

logger.Error($"Failed to cast config { key } of type { output.GetType() } to type { typeof(T) }!");

这样您就可以验证您的声明,即这两种类型是相同的。

【讨论】:

    猜你喜欢
    • 2020-10-13
    • 2011-11-15
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多