在Java中将类型转换为Java.Lang.Object转换为MonoDroid中的本机CLR类型

时间:2011-07-06 09:31:31

标签: xamarin.android

如何将Java.Lang.Object强制转换为某种原生类型?

示例:

ListView适配器包含本机类型Message的实例。当我试图从ListView获取SelectedItem时,它返回转换为Java.Lang.Object的Message类型的实例,但是我找不到将Java.Lang.Object强制转换回Message的解决方案。

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

请帮助。

8 个答案:

答案 0 :(得分:42)

经过长时间的调试,找到了解决方案:

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

答案 1 :(得分:8)

从Spinner获取本机类型的最不可思议的方法是调用

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

答案 2 :(得分:5)

我使用了以上答案的代码,它对我来说很好用

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

我能够从微调器中获取我的位置对象

答案 3 :(得分:1)

对于泛型集合,正确的答案是使用JavaList,它是一个Java.Lang.Object并且还实现了IList。但它涉及更多的工作,这是肯定的。这实际上只是Java的ArrayList实现的适配器。

答案 4 :(得分:1)

您可以随时尝试使用JavaCast&lt;&gt;方法(大多数视图实现了这个)(未经测试):

var message = list.SelectedItem.JavaCast&lt;消息&gt;();

答案 5 :(得分:1)

如果由于某种原因无法实现GetChildAtPosition,则将该对象序列化为json字符串,然后将该字符串反序列化为本机类。

答案 6 :(得分:0)

以上所有答案都是正确的,但我发现最简单的方法是将对象作为Java.Lang.Object的子类。

例如我正在Monotouch中编写一个Android应用程序,使用ExpandableListAdapter模仿iOS中UITableView的概念,它需要相当于UITableViewCells,所以我从Java.Lang.Object中继承了单元格对象,允许我实现一个ExpandableListAdapter的子类,如

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

答案 7 :(得分:0)

这对我有用:

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;