mironych
mironych

Reputation: 2978

Type cast from Java.Lang.Object to native CLR type in MonoDroid

How to cast Java.Lang.Object to some native type?

Example:

ListView adapter contains instances of native type Message. When i am trying to get SelectedItem from ListView it returns instance of Message type casted to Java.Lang.Object, but I can't find solution to cast Java.Lang.Object back to Message.

var message = (Message)list.SelectedItem;
// throws  Error    5   Cannot convert type 'Java.Lang.Object' to 'Message'

Please Help.

Upvotes: 19

Views: 13999

Answers (8)

Kalpesh Popat
Kalpesh Popat

Reputation: 1526

If for some reason GetChildAtPosition is not possible, serialise the object to json string and then deserialise the string back to native class.

Upvotes: 1

devil_coder
devil_coder

Reputation: 1135

I used this code from above answer and it works fine to me

    public static class ObjectTypeHelper
{
    public static T Cast<T>(this Java.Lang.Object obj) where T : class
    {
        var propertyInfo = obj.GetType().GetProperty("Instance");
        return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
    }
}

and this is how I used

var selectedLocation = locationSpinner.SelectedItem.Cast<Location>();

I am able to get my location object fine from spinner

Upvotes: 5

Ali Yousefi
Ali Yousefi

Reputation: 2765

it's work for me:

public class HolderHelper<T> : Java.Lang.Object {
    public readonly T Value;

    public HolderHelper (T value)
    {
        this.Value = value;
    }
}

test:

chkFileName.Tag = new HolderHelper<LinkInfo> (item);
LinkInfo link= (chkFileName.Tag as HolderHelper<LinkInfo>).Value;

Upvotes: 0

Jon Bates
Jon Bates

Reputation: 3183

The least magical way of getting a native type from the Spinner is to call

    message = ((ArrayAdapter<Message>)list.Adapter).GetItem(list.SelectedItemPosition);

Upvotes: 9

David van Dugteren
David van Dugteren

Reputation: 4119

All of the above answers are correct but I found the simplest way for my case was to make the object a subclass of Java.Lang.Object.

For example I'm writing a Android app in Monotouch, mimicking the concept of a UITableView in iOS using the ExpandableListAdapter, which requires the equivalent of UITableViewCells, so I subclassed cell objects from Java.Lang.Object allowing me to implement a subclass of ExpandableListAdapter such as

public override Java.Lang.Object GetChild(int position, int childPosition)

Etc.

Upvotes: 0

samus
samus

Reputation: 6202

You could always try the JavaCast<> method (most of the views implement this)(not tested):

var message = list.SelectedItem.JavaCast< Message >();

Upvotes: 1

imgen
imgen

Reputation: 3133

For generic collections, the right answer would be to use JavaList, which is a Java.Lang.Object and also implements IList. But it involves more work that's for sure. This is actually just an adapter for Java's ArrayList implementation.

Upvotes: 1

mironych
mironych

Reputation: 2978

After long time debuging, have found the solution:

public static class ObjectTypeHelper
{
    public static T Cast<T>(this Java.Lang.Object obj) where T : class
    {
        var propertyInfo = obj.GetType().GetProperty("Instance");
        return propertyInfo == null ? null : propertyInfo.GetValue(obj, null) as T;
    }
}

Usage example:

 var message = list.GetItemAtPosition(e.Position).Cast<Message>();
 bundle.PutInt("Message", message.ID);

After careful sdk study have found MonoDroid integrated extension for this purpose:

public static TResult JavaCast<TResult>(this Android.Runtime.IJavaObject instance)
where TResult : class, Android.Runtime.IJavaObject
Member of Android.Runtime.Extensions

Upvotes: 46

Related Questions