2015-01-16 3 views
2

Я ищу, чтобы использовать советы от this article, чтобы подтолкнуть покрытие кода по моему проекту ближе к 100%. В частности, последний раздел, который описывает идею обходного пути к методам, которые я не контролирую или иным образом не могу вводить. Необработанная версия Task, приведенная в этой статье, работает как прелесть, но у меня возникли проблемы с получением общей версии Task<T> для работы.Конструктор на универсальном классе имеет недопустимые аргументы

Скорее всего, я просто пропустил что-то очевидное.

Мой awaiter (отладочные флаги удалены для краткости) является:

public class EnsureCodeCoverageAwaiter<T> : INotifyCompletion 
{ 
    private readonly TaskAwaiter<T> taskAwaiter; 

    private bool forceAsync; 

    public EnsureCodeCoverageAwaiter(Task<T> task) 
    { 
     this.taskAwaiter = task.GetAwaiter(); 
     this.forceAsync = true; 
    } 

    public bool IsCompleted 
    { 
     get 
     { 
      if (this.forceAsync) 
       return false; 
      return this.taskAwaiter.IsCompleted; 
     } 
    } 

    public T GetResult() 
    { 
     this.forceAsync = false; 
     return this.taskAwaiter.GetResult(); 
    } 

    public void OnCompleted(Action continuation) 
    { 
     this.forceAsync = false; 
     this.taskAwaiter.OnCompleted(continuation); 
    } 
} 

И мой awaitable является:

public class EnsureCodeCoverageAwaitable<T> 
{ 
    private Task<T> _task; 

    public EnsureCodeCoverageAwaitable(Task<T> task) 
    { 
     _task = task; 
    } 

    public EnsureCodeCoverageAwaiter<T> GetAwaiter<T>() 
    { 
     return new EnsureCodeCoverageAwaiter<T>(_task); 
    } 
} 

Проблема, по мнению составителя, на этой последней строке GetAwaiter<T> способ. Компилятор говорит мне:

лучший перегружен матч метод EnsureCodeCoverageAwaiter (Task <T>) имеет некоторые недопустимые аргументы

Если я использую набор инструментов Visual Studio для «сгенерировать конструктор заглушки» из той же линии , он генерирует второй конструктор в EnsureCodeCoverageAwaiter с той же самой сигнатурой, что и существующий, и ошибка остается. (Я могу продолжать использовать тот же инструмент для создания все более идентичных контуров конструктора.)

Когда я смотрю на intellisense при построении этой строки кода, конструктор говорит, что ожидает Task<T> и переменную, которую я передаю он утверждает, что имеет тип Task<T>.

Я пропустил что-то о дженериках здесь?

ответ

7

Это проблема:

public EnsureCodeCoverageAwaiter<T> GetAwaiter<T>() 

Вы не хотите, чтобы быть универсальным методом введения нового параметра типа T - вы просто хотите использовать параметр типа типа. Так что вы хотите:

public EnsureCodeCoverageAwaiter<T> GetAwaiter() 

компилятор должен дать вам предупреждение об этом:

CS0693: Параметр Тип 'T' имеет то же имя в качестве параметра типа от внешнего вида 'EnsureCoverageAwaitable<T>'

Всегда проверяйте предупреждения компилятора :)

+1

«Старый» компилятор (VS2010, .NET 4) также дает предупреждение: 'Warning - Type parameter ' T 'имеет то же имя, что и параметр типа из внешнего типа Foo ' ' – Styxxy

+0

@Styxxy: Отлично, спасибо. Вынесут ласковые слова :) –

+0

@Styxxy: Doh! Мои различные панели автоматически скрываются (чтобы увеличить пространство редактора), поэтому я даже не думал искать предупреждение. Просто встроенная ошибка в редакторе.:) – David

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