Подтвердить что ты не робот

Тип, отлитый от Java.Lang.Object для родного типа CLR в MonoDroid

Как отличить Java.Lang.Object к некоторому родному типу?

Пример:

Адаптер ListView содержит экземпляры сообщения типа native. Когда я пытаюсь получить SelectedItem из ListView, он возвращает экземпляр типа Message, переданный в Java.Lang.Object, но я не могу найти решение для переноса Java.Lang.Object обратно в Message.

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

Пожалуйста, помогите.

4b9b3361

Ответ 1

После долгой отладки нашли решение:

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

Пример использования:

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

После тщательного изучения sdk для этой цели было установлено интегрированное расширение MonoDroid:

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

Ответ 2

Самый малый способ получить собственный тип из Spinner - вызвать

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

Ответ 3

Я использовал этот код из ответа выше, и он отлично работает для меня

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

и именно так я использовал

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

Я могу получить объектив моего местоположения от spinner

Ответ 4

Для общих коллекций правильным ответом будет использование JavaList, который является Java.Lang.Object, а также реализует IList. Но это требует больше работы, что точно. Это на самом деле просто адаптер для реализации Java ArrayList.

Ответ 5

Вы всегда можете попробовать метод JavaCast < > (большинство представлений реализует это) (не тестировалось):

var message = list.SelectedItem.JavaCast < Сообщение > ();

Ответ 6

Все приведенные выше ответы верны, но я нашел самый простой способ для моего дела - сделать объект подклассом Java.Lang.Object.

Например, я пишу приложение Android в Monotouch, подражая концепции UITableView в iOS с помощью ExpandableListAdapter, для чего требуется эквивалент UITableViewCells, поэтому я подклассифицировал объекты ячеек из Java.Lang.Object, что позволило мне реализовать подкласс ExpandableListAdapter, например

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

Etc.

Ответ 7

он работает для меня:

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

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

Тест:

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