Ошибка компилятора VS2010 "не присваивается типу параметра T", я считаю, что это не проблема ограничений - PullRequest
1 голос
/ 06 января 2012

Не думаю, что это носки, связанные с носорогом.

Это ошибка компилятора?

Строка во 2-м блоке кода ниже ОШИБКИ: комментарий дает предупреждение компилятору, и я не понимаю, почему. Еще больше меня удивило то, что блок 3 работает.

Этот работает нормально, поэтому я преобразовал его в Generic ActivatePresenterAction2

private void ActivatePresenterAction1(IListViewHelper<PairDirEntry> lvh)
{
    var args = lvh.GetArgumentsForCallsMadeOn(
            x => x.ActionOnActivateItem(Arg<Action<PairDirEntry>>.Is.Anything));
    Assert.That(args.Count, Is.EqualTo(1));
    Assert.That(args[0].Length, Is.EqualTo(1));
    var action = (Action<PairDirEntry>)(args[0][0]); // extract the ActivateOnItem action 
    action(_pairDirEntry); // as if ActionOnActivateItem()
}

Эта работа не компилируется в закомментированной строке

private void ActivatePresenterAction2<T>(IListViewHelper<T> lvh) where T : class
{
    var args = lvh.GetArgumentsForCallsMadeOn(
            x => x.ActionOnActivateItem(Arg<Action<T>>.Is.Anything));
    Assert.That(args.Count, Is.EqualTo(1));
    Assert.That(args[0].Length, Is.EqualTo(1));
    var action = (Action<T>)(args[0][0]); // extract the ActivateOnItem action 
    // 
    // ERROR: is not assignable to parameter type T on hliighted line
    // marking the parameter _pairDirEntry
    // 
    action(_pairDirEntry); // as if ActionOnActivateItem()
}

Это изменение в общем случае работает нормально.

ActivatePresenterAction3(_stubSearchResultListViewHelper)(_pairDirEntry);

private Action<T> ActivatePresenterAction3<T>(IListViewHelper<T> lvh) where T : class
{
    var args = lvh.GetArgumentsForCallsMadeOn(
            x => x.ActionOnActivateItem(Arg<Action<T>>.Is.Anything));
    Assert.That(args.Count, Is.EqualTo(1));
    Assert.That(args[0].Length, Is.EqualTo(1));
    return (Action<T>)(args[0][0]);
}

Ответы [ 2 ]

2 голосов
/ 06 января 2012

Чтобы подробнее узнать ответ SLaks, рассмотрим этот класс:

class C<T>
{
    private T t; //assume that this gets assigned somehow
    private void M<T>(Action<T> action)
    {
        action(this.t);
    }
}

Он не будет компилироваться, поскольку параметр T метода скрывает параметр T класса.Они не относятся к одному и тому же типу, даже если имеют одинаковое имя.Тип аргумента действия отличается от типа поля t.

. Это можно исправить, удалив параметр type из метода:

class C<T>
{
    private T t; //assume that this gets assigned somehow
    private void M(Action<T> action)
    {
        action(this.t);
    }
}

Теперь действие действияАргумент равен того же типа, что и поле t.

2 голосов
/ 06 января 2012

Как ясно указывает на ошибку компилятора, _pairDirEntry не является T, поэтому вы не можете передать его делегату, который принимает T.

...