2010-09-08 5 views
12

Я добавил ковариантный интерфейс для нашего проекта:сбоя сборки в тестовом проекте блока с аксессорами проекта, содержащим общековариантные типами

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(); 

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

Could not load type 'GenericInheritanceTest.IPresenter_Impl`1' from assembly 'GenericInheritanceTest_Accessor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because it declares a covariant or contravariant type parameter and is not an interface or delegate.

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

+0

Вам следует избегать частных аксессуаров в целом - они вызывают слишком жесткую связь между тестами и производственным кодом. – Grzenio

+0

Да, спасибо, но у меня есть уже существующий проект с 120k loc и хорошим использованием частных аксессуаров, поэтому он не будет просто кончиком пальца для его переделки. – Enyra

ответ

12

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

Согласно записи в блоге Брюса Таймана, разработка the private accessor feature была остановлена ​​и может быть удалена в будущих версиях Visual Studio. Возможные варианты, перечисленные являются:

  1. Use the Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject class to assist in accessing internal and private APIs in your code. This is found in the Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll assembly.

  2. Create a reflection framework that would be able to reflect off your code to access internal or private APIs.

  3. If the code you are trying to access is internal, you may be able to access your APIs using the InternalsVisibleToAttribute so your test code can have access to the internal APIs.

+3

Поздний ответ, но спасибо :) Да, частные аксессоры устарели, в то время как мы удалили всех частных аксессуаров в нашем проекте. Из вашего списка решений я предпочитаю пункт 4. Улучшить тестируемость с хорошей структурой объекта (IoC) :) – Enyra

0

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

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

private delegate TResult Action<TResult>(); 

Изменен:

private delegate TResult Action<out TResult>(); 

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

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

Таким образом, одна стратегия может быть исправна ch для:

"<out" 

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

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^