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