【问题标题】:System.InvalidCastException while casting an object type to custom class将对象类型转换为自定义类时发生 System.InvalidCastException
【发布时间】:2018-06-05 02:40:29
【问题描述】:

今天在处理我的代码时遇到了一个阶段,我需要将对象类型转换为我的自定义类,这应该非常简单,但我最终解决了几个小时 System.InvalidCastException,最后我最终使用了 JsonConvert完成工作。

我不确定是否有更好的方法来处理这个问题,如果有的话,我想知道我可以做得更好。

Given 是我的自定义类的结构

using SQLite.Net.Attributes;
namespace DataContract
{
public class Event
{
    #region Properties
    [PrimaryKey]
    public int Id { get; set; }

    public string Name { get; set; }

    public DateTime EventDateTime { get; set; }

    #endregion
}
}

Event 类位于 DataContract 共享项目中,我的项目文件夹结构如下所示,

使用 EntityFramework 我从我的 sqlite 数据库中获得了一个 List<Event>,我正在使用这个列表在我的 android 的 tableview 中显示元素,我在我的列表中一次浏览一个项目并尝试将它转换为我的自定义事件类。

给出的是我尝试过的相同代码

//tableItems is my IList<object>
var item = tableItems[position];

        var view = convertView;
        if (view == null)
        {
            view = context.LayoutInflater.Inflate(Resource.Layout.NativeAndroidEventCell, null);
        }


        if (item.GetType().FullName.Equals("DataContract.Event"))
        {
                  var x = item as DataContract.Event; // returns null
                  var y = (DataContract.Event)item; // cast exception
                var z = item.GetType().GetField("Name"); // returns null    

        }

图像中给出了我得到的异常,我无法在此处看到堆栈跟踪,因为它显示为空

当我在控制台中查看 item 变量的值时,我看到它向我显示了从数据库返回的确切值,甚至在类型列中显示了正确的类型,但由于某种原因,当我单步执行代码,x 的值为空。

作为我最后的手段,我最终使用了JsonConvert 类并做了类似的事情

if (item.GetType().FullName.Equals("DataContract.Event"))
        {
           //Not sure if this is the right approach here but it works
            var serializedObject = JsonConvert.SerializeObject(item, Formatting.Indented);
            var deserializedObject = JsonConvert.DeserializeObject<DataContract.Event>(x);

            view.FindViewById<TextView>(Resource.Id.textView1).Text = deserializedObject.Name;
            view.FindViewById<TextView>(Resource.Id.textView2).Text = deserializedObject.EventDateTime.ToString();
        }

JsonConvert 工作,我能够解决我的问题,但我更关注的是知道我是否可以比使用 JsonConvert 更好地解决这个问题,或者我所做的是否正确。请推荐

【问题讨论】:

  • item 不是已经属于 DataContract.Event 类型了吗?
  • 听起来您可能已经在多个程序集中定义了事件,甚至可能在不同上下文中加载的同一个程序集中定义了事件。 tableItems 究竟是如何填充的?
  • @mikez 说了什么,它抱怨的确切完整名称是什么
  • @JamesT 不,它不是,如代码中所述,它从 List 类型的 tableItems 中获取其值
  • @mikez 用我的文件夹结构更新了我的问题,你认为这是问题所在吗? tableItems 也是一个 IList 想要保持它的通用性,因为同一个视图将在多个地方使用,它从 UI 层获取数据,可以是 List

标签: c# casting xamarin.android json.net


【解决方案1】:

实际上在阅读了几遍并进行了一些猜测之后,这就是您的问题。

您在下面声明的 Event 类,例如

List<Event> tableItems ...

“不”指向与您尝试在此处强制转换时完全相同的类

(DataContract.Event)item;

这可以通过右键单击这两种类型并选择转到定义来确认,它们可能是不同的地方。

最可能的原因

  1. 一个是生成的代理(如果这是来自 WCF 或通过网络),一个是具体类
  2. 另一个可能的原因是它们所在的同一程序集的不同版本。检查您的参考资料

还可以尝试断点代码,并确定这些类型是否确实指向同一个地方。这就是问题所在,您需要以某种方式纠正它。

另请注意:如果您正在处理代理和具体类,则不能强制转换它们(即使它们完全相同),您将不得不手动复制属性或使用自动映射器之类的东西,或者像您正在进行序列化和反序列化一样

【讨论】:

  • 感谢您的快速响应,我确实检查了 tableItems 是 IList 类型的,它从 UI 层获取数据,然后我在运行时根据其中存在的内容将它们转换为我的应用程序的特定页面,例如页面 A 返回 List 和页面 B 返回 List 这样做有意义
【解决方案2】:

经过长时间的研究,我最终使用自己的 JSONSerialization 方法来处理问题中提到的转换

var serializedObject = JsonConvert.SerializeObject(item, Formatting.Indented);
            var deserializedObject = JsonConvert.DeserializeObject<DataContract.Event>(x);

            view.FindViewById<TextView>(Resource.Id.textView1).Text = deserializedObject.Name;
            view.FindViewById<TextView>(Resource.Id.textView2).Text = deserializedObject.EventDateTime.ToString();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-18
    • 2020-04-16
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多