简体   繁体   中英

System.InvalidCastException while casting an object type to custom class

Today working on my code I came across a phase where i needed to cast an object type to my custom class which should have been very simple, but I ended up hours resolving System.InvalidCastException , finally I ended up using JsonConvert to get the job done.

I am not really sure if there was a better way to handle this, if there is I would like to know what I could have done better.

Given is the structure of my custom class

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

The Event class is inside a DataContract shared project and my folder structure of the project is given below,

解决方案结构

Using EntityFramework I am getting a List<Event> from my sqlite database and I am using this list to display elements in my tableview for android, I go through one item at a time in my list and try to cast it to my custom Event class.

Given is the code for the same which i tried

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

        }

The exception I get is given in the image, I am unable to see the stacktrace here as it shows null

在此处输入图片说明

When I watch the value of item variable in the console I see that it shows me the exact values of what is being returned from the database and it even shows me the correct type in the type column but for some reason when i step through the code the value of x is null.

在此处输入图片说明

As my last resort I ended up using JsonConvert class and did something like this

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();
        }

The JsonConvert works and I am able to resolve my issue, but what I am more looking at is to know if I could have done better to resolve this than using JsonConvert Or what I did was correct. Please suggest

Actually after reading this several times and some guess work, here is your problem.

The Event class you declare below eg

List<Event> tableItems ...

is "not" pointing to the exactly the same class as when you are trying to cast here

(DataContract.Event)item;

This maybe confirmed by right clicking both types and selecting go to definition, they are probably different places.

Most likely cause

  1. One is a generated proxy (if this is coming from WCF, or over the wire), one is the concrete class
  2. Another likely cause, you have different versions of the same assembly in which they live. Check your references

Also try and break point the code, and determine if these types are indeed pointing to the same place. This is the problem and you need to somehow rectify it.

Also note : if you are dealing with proxies and concrete classes you cant cast them (even if they are exactly the same) you will have to copy the properties across manually or use something like automapper or like you are doing serialize and deserialize

After long hours of research, I ended up using my own JSONSerialization approach to handle the casting as mentioned in the question

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM