Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Xamarin.Android绑定项目中的多态性_C#_Binding_Xamarin.android - Fatal编程技术网

C# Xamarin.Android绑定项目中的多态性

C# Xamarin.Android绑定项目中的多态性,c#,binding,xamarin.android,C#,Binding,Xamarin.android,我正在尝试为一个专有的Android库生成Xamarin绑定(换句话说,不幸的是,我不能在这里共享这个库)。然而,我遇到了多态性的问题。情况是这样的 该库公开了3个接口Location,MobilityProfile和Trip都扩展了接口Reading 该库还有一个接口Measurement,其中包含Reading getReading()方法,该方法应始终返回上述3个接口之一(位置,移动应用程序或行程) 我生成了绑定并编译了绑定项目,效果很好。下一步是在我的Xamarin项目中使用Xamari

我正在尝试为一个专有的Android库生成Xamarin绑定(换句话说,不幸的是,我不能在这里共享这个库)。然而,我遇到了多态性的问题。情况是这样的

该库公开了3个接口
Location
MobilityProfile
Trip
都扩展了接口
Reading

该库还有一个接口
Measurement
,其中包含
Reading getReading()
方法,该方法应始终返回上述3个接口之一(
位置
移动应用程序
行程

我生成了绑定并编译了绑定项目,效果很好。下一步是在我的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.");
    }
}

现在,由于
reading
参数的类型为
IReadingInvoker
,因此我最终处于
default
状态。有人能告诉我如何解决这个问题吗?

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

根据您的注释和一些附加检查,尝试下面的方法,并在每个方法的catch括号中设置断点,以确认可以显式强制转换到一个派生接口

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语句来确定类型有点不方便,因为在这个堆栈溢出问题中突出显示了以下原因:


编辑:在review中,您可能需要显式强制转换,这意味着您无法可靠地使用条件运算符,因为显式强制转换将在无法强制转换对象时引发异常

Xamarin.Android绑定库在您的库以这种方式返回Java实例时无法将其映射到C#接口,因此强制转换无法工作

Plz对其他类型使用
Android.Runtime.Extensions.JavaCast(readingstace)
等等

可能需要
try catch


干杯。

我已经按照你的建议试过了,但不幸的是我得到了同样的结果。代码在
else
块中结束,并引发异常:“不支持处理类型'IReadingInvoker'。@MauritsvanBeusekom进行了快速编辑,以便您可以只测试显式转换。正如我所料,这会导致相同的问题。我的意思是在引擎盖下,
as
关键字也执行显式转换。我觉得这与Xamarin.Android需要一个实现
IJavaObject
类型的对象有关,因此生成了一个实现
Java.Lang.object
类的
I…Resolver
类。然而,我有点迷失在如何、为什么以及如何正确处理这个问题上,我可以解决我的问题:谢谢@tuyế这正是我要找的信息。如果其他人想知道,可以在此处找到更多信息: