You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin.Android绑定项目中使用Kotlin.Result?

解决Xamarin.Android中Kotlin.Result的取值与泛型问题

核心问题分析

你遇到的是Xamarin.Kotlin.StdLib绑定不完整导致的问题:1.7.20.1版本缺失Kotlin.Result的泛型实现与核心方法(如getOrThrow、getOrNull),旧版本的ThrowIfFailure也已移除,靠ToString解析的方法仅适用于简单类型,对复杂类完全无效。

可行解决方案

1. 反射调用Kotlin.Result的原生方法

Kotlin.Result在JVM编译后其实保留了isSuccess()、isFailure()、getOrNull()、exceptionOrNull()这些核心方法,只是Xamarin绑定未生成对应的C#封装。你可以通过反射直接调用这些方法:

using System.Reflection;

public static T GetResultValue<T>(object resultInstance)
{
    Type resultType = resultInstance.GetType();
    
    // 判断是否为成功结果
    MethodInfo isSuccessMethod = resultType.GetMethod("isSuccess");
    bool isSuccess = (bool)isSuccessMethod.Invoke(resultInstance, null);
    
    if (isSuccess)
    {
        // 获取成功值
        MethodInfo getOrNullMethod = resultType.GetMethod("getOrNull");
        return (T)getOrNullMethod.Invoke(resultInstance, null);
    }
    else
    {
        // 获取失败异常并抛出
        MethodInfo exceptionOrNullMethod = resultType.GetMethod("exceptionOrNull");
        Exception ex = (Exception)exceptionOrNullMethod.Invoke(resultInstance, null);
        throw ex ?? new InvalidOperationException("Result failed with no exception");
    }
}

使用示例:

// 假设yourResult是从绑定库获取的Result<SomeClass>实例
SomeClass value = GetResultValue<SomeClass>(yourResult);

2. 调整Xamarin绑定元数据(Metadata.xml)

如果能修改绑定项目的元数据,可以手动添加Result类的方法绑定,让Xamarin生成对应的C#封装:

在绑定项目的Metadata.xml中添加以下内容(根据反编译aar中Result的实际方法签名调整):

<attr path="/api/package[@name='kotlin']/class[@name='Result']" name="visibility">public</attr>
<attr path="/api/package[@name='kotlin']/class[@name='Result']/method[@name='getOrNull']" name="managedName">GetOrNull</attr>
<attr path="/api/package[@name='kotlin']/class[@name='Result']/method[@name='isSuccess']" name="managedName">IsSuccess</attr>
<attr path="/api/package[@name='kotlin']/class[@name='Result']/method[@name='exceptionOrNull']" name="managedName">ExceptionOrNull</attr>

添加后重新生成绑定项目,就能直接调用这些方法,无需反射。

3. 获取Result的泛型类型

要获取Result的泛型参数类型,同样可以通过反射实现:

public static Type GetResultGenericType(object resultInstance)
{
    Type resultType = resultInstance.GetType();
    // 若绑定后的Result是泛型类型,直接取泛型参数
    if (resultType.IsGenericType)
    {
        return resultType.GetGenericArguments()[0];
    }
    // 若为非泛型绑定,通过获取值的类型间接判断
    MethodInfo getOrNullMethod = resultType.GetMethod("getOrNull");
    object value = getOrNullMethod.Invoke(resultInstance, null);
    return value?.GetType();
}

4. 备选方案:Kotlin端封装(若可修改原包)

如果能控制原Kotlin库的代码,可以在Kotlin端封装一层,将Result的结果拆分为更易被Xamarin处理的形式,比如:

// 直接返回Nullable类型
fun yourOriginalFunction(): String? {
    return runCatching { originalResultReturningFunction() }.getOrNull()
}

// 或者返回结果与异常的Pair
fun yourOriginalFunction(): Pair<String?, Throwable?> {
    val result = originalResultReturningFunction()
    return Pair(result.getOrNull(), result.exceptionOrNull())
}

内容的提问来源于stack exchange,提问作者albertb22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 07:25:32