【问题标题】:Polymorphism in Xamarin.Android binding projectXamarin.Android 绑定项目中的多态性
【发布时间】:2018-10-01 05:45:39
【问题描述】:

我正在尝试为专有的 Android 库生成 Xamarin 绑定(换句话说,很遗憾,我无法在此处共享此库)。但是我遇到了多态性的问题。这是情况。

该库公开了 3 个接口 LocationMobilityProfileTrip 都扩展了接口 Reading

该库还有一个接口Measurement,其中包含Reading getReading(); 方法,该方法应始终返回上述3 个接口之一(LocationMobilityProfileTrip)。

我生成了绑定并编译了运行良好的绑定项目。下一步是在我的 Xamarin 项目中使用 Xamarin.Android 绑定,如下所示:

public void ProcessReading(IReading reading)
{
    if (reading == null)
        return null;

    switch (reading)
    {
        case ILocation location:
            // Process location
            break;
        case IMobilityProfile mobilityProfile:
            // Process mobility profile
            break;
        case ITrip trip:
            // Process trip
            break;
        default:
            throw new NotSupportedException($"Processing the type '{reading.GetType().FullName}' is not supported.");
    }
}

现在我在default 条件下结束,因为reading 参数的类型是IReadingInvoker。谁能告诉我如何解决这个问题?

【问题讨论】:

    标签: c# binding xamarin.android


    【解决方案1】:

    当您的库以这种方式返回 Java 实例时,Xamarin.Android 绑定库无法将 Java 实例映射到其 C# 接口,因此强制转换永远不会起作用。

    其他类型请使用Android.Runtime.Extensions.JavaCast<ILocation>(readingInstace)等。

    try-catch 可能是必需的。

    干杯。

    【讨论】:

    【解决方案2】:

    因为您正在接收基本接口对象,所以 switch 语句将无法将其识别为其他子接口之一。至少不是你期望的那样。

    根据您的评论和一些额外的检查,尝试下面的方法,并在每个捕获括号中设置断点,以确认可以显式转换为您的派生接口之一。

    public void ProcessReading(IReading reading)
    {
        if (reading == null)
            return null;
    
        try
        {
            var castReading = (ILocation) reading; 
            // Process location
        }
        catch
        {
            //exception hit
        }
    
        try
        {
            var castReading = (IMobilityProfile ) reading; 
            // Process mobility profile
        }
        catch
        {
            //exception hit
        }
    
        try
        {
            var castReading = (ITrip ) reading; 
            // Process trip
        }
        catch
        {
            //exception hit
        }
    }
    

    绝对不是最整洁的方式。但是由于这个堆栈溢出问题中突出显示的原因,使用 switch 语句来确定类型有点麻烦:Here.

    编辑: 在审查中看起来您需要显式转换,这意味着您不能可靠地使用条件运算符,因为如果无法转换对象,显式转换将引发异常。 Source.

    【讨论】:

    • 我已经按照您的建议进行了尝试,但不幸的是我得到了相同的结果。代码在else 块中结束并抛出异常:“不支持处理类型'IReadingInvoker'。”
    • @MauritsvanBeusekom 进行了快速编辑,以便您可以测试显式演员表。
    • 正如我所料,这会导致同样的问题。我的意思是在幕后as 关键字也执行显式转换。我觉得这与 Xamarin.Android 需要一个实现IJavaObject 类型的对象有关,因此生成一个实现Java.Lang.Object 类的I...Resolver 类。但是,我对如何以及为什么以及如何以可以解决我的问题的方式正确处理这个问题有点迷茫:docs.microsoft.com/en-us/xamarin/android/platform/…
    猜你喜欢
    • 2014-03-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 2015-11-21
    • 2014-07-13
    相关资源
    最近更新 更多