Ошибка CS0115: не найден подходящий метод для переопределения в проекте библиотеки привязок Xamarin
Я создал проект библиотеки привязок, чтобы иметь возможность запускать файл Android .aar. Одна из нескольких ошибок, которые я получил, была:
Error CS0115 'Call.OnWarning(IDictionary)': no suitable method found to override TwilioBindings C:\...\TwilioBindings\obj\Debug\generated\src\Com.Twilio.Voice.Call.cs;
И для ее решения я проверил api.xml и увидел, что метод onWarning имеет параметр с типом java.util.HashMap:
<method abstract="false" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
<parameter name="p0" type="java.util.HashMap">
</parameter>
</method>
Класс Call расширяет InternalCall, который реализует RTCMonitorCommand.Listener, и после того, как я проверил файл api.xml, я заметил, что метод onWarning имеет следующее определение:
InternalCall:
<method abstract="false" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
<parameter name="warningDetails" type="java.util.HashMap<java.lang.String, java.lang.Object>">
</parameter>
</method>
RTCMonitorCommand.Listener:
<method abstract="true" deprecated="not deprecated" final="false" name="onWarning" native="false" return="void" static="false" synchronized="false" visibility="public">
<parameter name="p0" type="java.util.HashMap<java.lang.String, java.lang.Object>">
</parameter>
</method>
Поэтому я пришел к выводу, что только класс Call имеет другой тип параметра.
Поэтому я написал следующую строку в Metadata.xml, чтобы изменить тип параметра метода onWarning в классе Call:
<attr path="/api/package[@name='com.twilio.voice']/class[@name='Call']/method[@name='onWarning' and count(parameter)=1 and parameter[1][@type='java.util.HashMap']]/parameter[1]" name="type">java.util.HashMap<java.lang.String, java.lang.Object></attr>
Ошибка ушла, но у меня возникли некоторые проблемы с использованием этого проекта привязок, и это строка в Metadata.xml, что я не уверен, что это правильно.
Кто-нибудь знает, был ли мой подход правильным?
Любая помощь должна быть оценена,
Спасибо.
2 ответа
У меня были проблемы при вызове метода из этой библиотеки привязки, и я подумал, что это вызвано некоторой ошибкой привязки, но затем, после поиска в журналах, я пришел к выводу, что проблема заключалась в том, что библиотека не смогла найти зависимость. На проект зависимостей ссылался проект связывания, но каким-то образом ссылка не работала. Так что я изменил ссылку и вместо ссылки на пакет я ссылался на пакет dll, и теперь он работает правильно.
Для будущих пользователей, которые столкнутся с этой ошибкой. У меня есть 2 сценария, которые вызвали у меня эту проблему, и их исправление приведено ниже:
Сценарий 1:
«Не найдено подходящего метода для переопределения», полученное после реализации члена интерфейса через метаданные.xml, чтобы исправить ошибку «[className] не реализует член интерфейса [memberName]» . Мой [имя класса]DefaultTimerBar
и мое имя члена интерфейсаITimeBar.SetEnabled(bool)
.
<!--Fixes The following metadata change will resolve "[className] does not implement interface member [memberName]",
however it will now give the error "DefaultTimeBar.SetEnabled(bool): no suitable method found to override"-->
<add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='DefaultTimeBar']">
<method name="setEnabled" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
<parameter name="p0" type="boolean"/>
</method>
</add-node>
<!--The fix for this scenario was to change the name of the method from "setEnabled" to "SetEnabled". This resolved both errors-->
<add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='DefaultTimeBar']">
<method name="SetEnabled" return="void" abstract="false" native="false" synchronized="false" static="false" final="false" deprecated="not deprecated" visibility="public">
<parameter name="p0" type="boolean"/>
</method>
</add-node>
Я подозреваю, что когда член интерфейса называется «getX()» или «setX()», компилятор видит это как свойство get/set. В приведенном выше случае дляsetEnabled(bool)
, если атрибут имени метода записан строчными буквами, метод будет реализован какoverride
. Впоследствии выдается ошибка: не найден подходящий метод для переопределения . При изменении на верхний регистр он будет реализован какvirtual
правильно. Мои рассуждения связаны с тем, что такое же поведение не происходит, когда имя метода не начинается с get/set в файле .aar.
Сценарий 2:
Ошибка [className].[methodName]: не найден подходящий метод для переопределения, полученного без предварительного преобразования метаданных для конкретного метода. Мой метод получил названиеSetFullScreen(bool)
поэтому я предположил, что это произошло из-за той же проблемы, когда компилятор неправильно рассматривал это как метод получения/установки. Мое решение состояло в том, чтобы удалить метод, а затем снова добавить его с заглавной буквой имени. Я просто скопировал сведения о методе из файла api.xml в каталоге проекта привязки.obj\Debug\api.xml
.
<remove-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='VideoPlayerViewExo']/method[@name='setFullScreen' and count(parameter)=1 and parameter[1][@type='boolean']]"/>
<add-node path="/api/package[@name='com.mycompany.mypackage']/class[@name='VideoPlayerViewExo']">
<method abstract="false" deprecated="not deprecated" final="false" name="SetFullScreen" jni-signature="(Z)V" bridge="false" native="false" return="void" jni-return="V" static="false" synchronized="false" synthetic="false" visibility="public">
<parameter name="fullscreen" type="boolean" jni-type="Z">
</parameter>
</method>
</add-node>