Метод с аргументом Object не примет ничего, кроме объекта

У нас есть функция VB.net со следующей сигнатурой в классе InitializerFactory:

Public Shared Function Create(ByRef ui As Object) As IModeInitializer

Я пытаюсь проверить эту функцию, передав макет пользовательского интерфейса (используя Rhino Mocks):

MainForm ui = mocks.StrictMock<MainForm>();
IModeInitializer item = InitializerFactory.Create(ref ui);

При попытке передать ui в качестве параметра я получаю следующие ошибки:

  • Лучшее соответствие перегруженного метода для «InitializerFactory.Create (ref object)» имеет некоторые недопустимые аргументы.
  • Аргумент '1': невозможно преобразовать из 'ref MainForm' в 'ref object'

В идеале решением было бы извлечь интерфейс из пользовательского интерфейса (или его класса, MainForm), но это ни в коем случае невозможно — это чрезвычайно раздутый класс.

Я также не могу объявить ui как Object, иначе я не могу издеваться над методами внутри него, поскольку методы не принадлежат к типу Object.

У меня вопрос - что я делаю не так?


person MunkiPhD    schedule 06.10.2009    source источник


Ответы (1)


Это просто из-за синтаксиса параметра ref. Проблема в том, что функция должна иметь возможность устанавливать ЛЮБОЙ тип объекта, так как это параметр по ссылке. Вы не можете просто передать ему ссылку на MainForm, что вы и пытаетесь сделать.

К сожалению, с этим API довольно сложно работать.

Вы можете справиться с этим, сначала назначив свой экземпляр объекту:

MainForm ui = mocks.StrictMock<MainForm>();
object uiObj = ui;
IModeInitializer item = InitializerFactory.Create(ref uiObj);
if (uiObj != ui) { 
    // Handle the case where the reference changed!
    ui = uiObj as MainForm; // May be null, if it's no longer a "MainForm"
}

Если вы хотите полностью понять это, вы можете прочитать Ковариантность и контравариантность. .

person Reed Copsey    schedule 06.10.2009
comment
Я пробовал это, но затем получаю следующую ошибку в NUnit: System.InvalidOperationException: объект '' не является фиктивным объектом. Я предполагаю, что речь идет об uiObj, поскольку это не так. просто объект, а не фиктивный объект. - person MunkiPhD; 06.10.2009
comment
Было бы очень полезно, если бы вы сказали, где произошла эта ошибка. Но я согласен с Ридом — это звучит как ужасный API. Должен ли он действительно иметь параметр by-ref? - person Jon Skeet; 06.10.2009
comment
@MunkiPhD: проблема не в этом. Приведение и присвоение объекту не меняет фактический тип объекта. У вас есть другая проблема внутри метода. - person Reed Copsey; 06.10.2009
comment
Да, API не самый лучший в некоторых областях, но «это то, что есть». - person MunkiPhD; 06.10.2009