我试图为" 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/