Тип, отлитый от 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'
Пожалуйста, помогите.
Ответы
Ответ 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;