Ошибка сборки в модульном тестовом проекте с аксессорами проекта, содержащего ковариантные типы - PullRequest
14 голосов
/ 08 сентября 2010

Я добавил ковариантный интерфейс в наш проект:

interface IView
{
}

interface IPresenter<out TView> where TView : IView
{
    TView View { get; }
}

Я создал несколько классов, реализующих эти интерфейсы:

class TestView : IView
{
}

class TestPresenter : IPresenter<TestView>
{
  public TestView View
  {
    get { return something; }
  }

  private void DoSomething()
  {
  }
}

И я могу использовать это без проблем:

IPresenter<IView> presenter = new TestPresenter();

Так что все кажется правильным, поэтому я предполагаю, что мое использование ковариации правильное.К сожалению, наши проекты модульных тестов содержат частные средства доступа из некоторых типов, расположенные в одном проекте, например ковариантный интерфейс, что приводит к ошибке сборки.

Не удалось загрузить тип 'GenericInheritanceTest.IPresenter_Impl`1' из сборки 'GenericInheritanceTest_Accessor, версия = 0.0.0.0, культура = нейтральная, PublicKeyToken = null ', поскольку она объявляет ковариантный или контравариантный параметр типа и не является интерфейсом или делегатом.

В чем именно заключается проблема?Есть ли сбой в моей реализации, соотв.как это исправить?Не может быть, что мы должны избегать аксессоров, как только мы используем ковариантные типы ???Можно ли предотвратить создание средств доступа для определенных типов для решения этой проблемы?

Ответы [ 3 ]

14 голосов
/ 15 сентября 2011

Это ошибка в Visual Studio 2010. Об этом сообщалось Microsoft Connect , но оно было закрыто и, очевидно, не будет исправлено.

Согласно записи в блоге Брюса Тайманаразработка функции частного доступа была остановлена ​​и может быть удалена в будущих версиях Visual Studio.Перечисленные возможные альтернативы:

  1. Используйте класс Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject для помощи в доступе к внутренним и частным API в вашем коде.Это можно найти в сборке Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll.

  2. Создать каркас отражения, который сможет отражать ваш код для доступа к внутренним или частным API.

  3. Если код, к которому вы пытаетесь получить доступ, является внутренним, вы можете получить доступ к своим API, используя InternalsVisibleToAttribute, чтобы ваш тестовый код мог иметь доступ к внутренним API.

1 голос
/ 24 мая 2015

Я боролся с этой ошибкой, а также получил ошибку: «BuildShadowTask» неожиданно завершился неудачей.Единственный способ избавиться от ошибки, когда я пытался разрешить ее здесь, это удалить ключевое слово out из обобщенных элементов, то есть ковариантного интерфейса.

На самом деле я получил эту ошибку, когда Решарпер предположил, что параметр типа может быть ковариантным:

private delegate TResult Action<TResult>(); 

Изменено на:

private delegate TResult Action<out TResult>();

К сожалению, мне пришлось снова изменить его и отключить предупреждение Resharper в комментарии:

// ReSharper disable once TypeParameterCanBeVariant 
private delegate TResult Action<TResult>();

OneСтратегия может заключаться в том, чтобы искать:

"<out"

в проекте и удалять ключевое слово out, просто чтобы его скомпилировать.Не очень элегантно, но и не очень элегантно со стороны Microsoft, потому что это было распространено пять лет назад через Microsoft Connect, и они решили просто закрыть проблему.Проблема в модульных тестовых проектах.Это не помогает перейти с платформы Visual Studio Unit Testing Framework на NUnit Testing Framework.

0 голосов
/ 27 июня 2016

Если вы используете Unity Interception, и ваш параметр помечен как out, Unity Interception вызовет эту ошибку.Причина этого в том, что Interception должен иметь возможность читать список параметров.Таким образом, как и в случае выше, если Resharper предупреждает, что параметр может быть ковариантным, это предупреждение следует игнорировать.

...