Ошибка 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&lt;java.lang.String, java.lang.Object&gt;">
    </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&lt;java.lang.String, java.lang.Object&gt;">
    </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&lt;java.lang.String, java.lang.Object&gt;</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>
Другие вопросы по тегам