On Mar 10, 2015, at 11:46 AM, Paul Johnson <[email protected]> wrote:
> When I'm building, I'm getting two errors, both are the same
>
> obj/Debug/generated/src/Com.Layer.Sdk.Internal.Query.ConversationQueryRepository.cs(65,113):
> error CS0508:
> `Com.Layer.Sdk.Internal.Query.ConversationQueryRepository.A(Com.Layer.Sdk.Query.Query)':
> return type must be `System.Collections.IList' to match overridden member
> `Com.Layer.Sdk.Internal.Query.QueryRepository.A(Com.Layer.Sdk.Query.Query)'
>
> The code generating this error is
>
> [Register ("a", "(Lcom/layer/sdk/query/Query;)Ljava/util/List;", "")]
> public override sealed
> global::System.Collections.Generic.IList<global::Com.Layer.Sdk.Messaging.Conversation>
> A (global::Com.Layer.Sdk.Query.Query p0)
> {
> if (id_a_Lcom_layer_sdk_query_Query_ == IntPtr.Zero)
> id_a_Lcom_layer_sdk_query_Query_ =
> JNIEnv.GetMethodID (class_ref, "a",
> "(Lcom/layer/sdk/query/Query;)Ljava/util/List;");
>
> global::System.Collections.Generic.IList<global::Com.Layer.Sdk.Messaging.Conversation>
> __ret =
> global::Android.Runtime.JavaList<global::Com.Layer.Sdk.Messaging.Conversation>.FromJniHandle
> (JNIEnv.CallObjectMethod (Handle, id_a_Lcom_layer_sdk_query_Query_, new
> JValue (p0)), JniHandleOwnership.TransferLocalRef);
> return __ret;
> }
>
> I'm not too sure, but is it the [Register...] line causing the problem as
> it's referencing java/util/list?
No.
The problem is the `override` keyword in the method declaration:
> public override sealed
> global::System.Collections.Generic.IList<global::Com.Layer.Sdk.Messaging.Conversation>
> A (global::Com.Layer.Sdk.Query.Query p0)
The base class method declaration uses IList, not IList<Conversation>. They are
different types, and thus the C# compiler doesn't like that.
The reason this happens is because of Java covariant return types: the base
class is just a List, while the derived method override is a
List<Conversation>, which is permitted. (Alternatively, this is fallout of Java
generics + type erasure...)
There are two possible workarounds:
1. Use metadata to "fixup" the return type:
<attr path="/the/path/to/method/a"
name="managedReturn">System.Collections.IList</attr>
The above will simply change the return type of the A() method, which should
satisfy the C# compiler.
2. Rename the method in Metadata, then implement the method in a partial class.
This technique is useful in a variety of scenarios:
<!-- Metadata -->
<attr path="the/path/to/method/a" name="managedName">_A</attr>
// PartialClass.cs:
partial class TheClass {
public override IList A (Query p0)
{
return _A (p0);
}
}
Why `_A`? Why *not*? :-)
(You might also want to change the visibility of _A to `internal` so that it
isn't publicly visible. Or you might want to keep it public, and pick a better
name.)
- Jon
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid