Xamarin.Android绑定库和Java返回类型协方差

时间:2016-12-09 14:20:09

标签: c# xamarin xamarin.android

我试图为" Kotlin"创建一个Bindings库。图书馆。 在将必要的 .jar 文件添加到Bindings项目并构建它之后,由于Java中可能存在返回类型协方差,我得到了很多编译错误,但是在C#中没有。其中一些我可以修改变换,但我遇到了以下情况:

其中一个生成的类是ClassReference,它实现了一个名为IKClass的接口,该接口也是由绑定生成的。该接口定义了以下成员:

global::System.Collections.ICollection Constructors {
    // Metadata.xml XPath method reference: path="/api/package[@name='kotlin.reflect']/interface[@name='KClass']/method[@name='getConstructors' and count(parameter)=0]"
    [Register ("getConstructors", "()Ljava/util/Collection;", "GetGetConstructorsHandler:Kotlin.Reflect.IKClassInvoker, Kotlin.Bindings")] get;
}

对于ClassReference类:

,这是为该成员的实现生成的代码
public unsafe global::System.Collections.Generic.ICollection<global::Kotlin.Reflect.IKFunction> Constructors {
    // Metadata.xml XPath method reference: path="/api/package[@name='kotlin.jvm.internal']/class[@name='ClassReference']/method[@name='getConstructors' and count(parameter)=0]"
    [Register ("getConstructors", "()Ljava/util/Collection;", "GetGetConstructorsHandler")]
    get {
        if (id_getConstructors == IntPtr.Zero)
            id_getConstructors = JNIEnv.GetMethodID (class_ref, "getConstructors", "()Ljava/util/Collection;");
        try {
            return global::Android.Runtime.JavaCollection<global::Kotlin.Reflect.IKFunction>.FromJniHandle (JNIEnv.CallObjectMethod (((global::Java.Lang.Object) this).Handle, id_getConstructors), JniHandleOwnership.TransferLocalRef);
        } finally {
        }
    }
}

因此,基本上,接口需要ICollection作为返回类型,但它的实现返回ICollection<IKFunction>,导致编译错误:

  

&#39;的ClassReference&#39;没有实现接口成员&#39; IKClass.Constructors&#39;。 &#39; ClassReference.Constructors&#39;无法实施&#39; IKClass.Constructors&#39;因为它没有匹配的返回类型&#39; ICollection&#39;。

我可以通过添加以下转换来解决这个问题:

<attr path="/api/package[@name='kotlin.jvm.internal']/class[@name='ClassReference']/method[@name='getConstructors' and count(parameter)=0]" name="managedReturn">System.Collections.ICollection</attr>

但是,生成的代码变为:

public unsafe global::System.Collections.ICollection Constructors {
    // Metadata.xml XPath method reference: path="/api/package[@name='kotlin.jvm.internal']/class[@name='ClassReference']/method[@name='getConstructors' and count(parameter)=0]"
    [Register ("getConstructors", "()Ljava/util/Collection;", "GetGetConstructorsHandler")]
    get {
        if (id_getConstructors == IntPtr.Zero)
            id_getConstructors = JNIEnv.GetMethodID (class_ref, "getConstructors", "()Ljava/util/Collection;");
        try {
            return global::Android.Runtime.JavaCollection<global::Kotlin.Reflect.IKFunction>.FromJniHandle (JNIEnv.CallObjectMethod (((global::Java.Lang.Object) this).Handle, id_getConstructors), JniHandleOwnership.TransferLocalRef);
        } finally {
        }
    }
}

导致另一个错误:

  

无法隐式转换类型&#39; System.Collections.Generic.ICollection&lt; Kotlin.Reflect.IKFunction&gt;&#39;到&#39; System.Collections.ICollection&#39;。存在显式转换(您是否错过了演员?)

我知道发生这种情况是因为,除了属性上的返回类型之外,生成的代码保持不变,并且它仍然返回ICollection<IKFunction>,因为ICollection<T>无法工作1}}没有&#34;继承/实施&#34; ICollection

要解决这个问题,我修改了我的转换以重命名属性,而不是更改它的返回类型:

<attr path="/api/package[@name='kotlin.jvm.internal']/class[@name='ClassReference']/method[@name='getConstructors' and count(parameter)=0]" name="name">ConstructorsGeneric</attr>

然后添加了partial class来实现接口定义的Property:

public sealed partial class ClassReference
{
    public global::System.Collections.ICollection Constructors
    {
        get
        {
            var genericConstructors = this.ConstructorsGeneric();
            return genericConstructors.ToList();
        }
    }
}

问题是,我有更多像这样的错误,而且我甚至不知道一旦项目建立后一切都能正常运行,所以,这里有我的问题:那里我可以通过一些更简单的方法来解决我错过的这类错误吗?

developer.xamarin 网站上的这个链接解释了自定义绑定,还涉及了Java协方差的主题,但我不认为它涵盖了我的情景: https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/customizing-bindings/java-bindings-metadata/

0 个答案:

没有答案