代码之家  ›  专栏  ›  技术社区  ›  Bug Hunter Zoro

系统将对象类型强制转换为自定义类时出现InvalidCastException

  •  1
  • Bug Hunter Zoro  · 技术社区  · 7 年前

    今天在编写代码的过程中,我遇到了一个阶段,我需要将一个对象类型强制转换到我的自定义类中,这本应该非常简单,但我最终花了几个小时来解决 System.InvalidCastException ,最终我使用 JsonConvert 完成工作。

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

    给出了自定义类的结构

    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
    }
    }
    

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

    Solution structure

    使用EntityFramework,我得到 List<Event> 从我的sqlite数据库中,我使用这个列表来显示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    
    
            }
    

    我得到的异常在图像中给出,我无法在这里看到stacktrace,因为它显示为null

    enter image description here

    当我看到 item 在控制台中,我看到它显示了从数据库返回的确切值,甚至在类型列中显示了正确的类型,但由于某种原因,当我逐步遍历代码时,x的值为null。

    enter image description here

    作为我最后的选择 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更好地解决这个问题,或者我所做的是正确的。请建议

    2 回复  |  直到 7 年前
        1
  •  0
  •   TheGeneral    7 年前

    实际上,在读了几遍这篇文章并进行了一些猜测之后,你的问题来了。

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

    List<Event> tableItems ...
    

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

    (DataContract.Event)item;
    

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

    最可能的原因

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

    还要尝试打断代码,并确定这些类型是否确实指向同一个位置。这就是问题所在,你需要以某种方式加以纠正。

    另请注意:如果您处理的是代理和具体类,您不能强制转换它们(即使它们完全相同),您必须手动复制属性,或者使用automapper之类的工具,或者像您正在进行序列化和反序列化一样

        2
  •  0
  •   Bug Hunter Zoro    7 年前

    经过长时间的研究,我最终使用了自己的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();