VS2010编译器错误“不能分配给参数类型T”不是一个约束问题我相信

问题描述:

我不认为它与犀牛模拟相关。VS2010编译器错误“不能分配给参数类型T”不是一个约束问题我相信

它是一个编译器错误?

ERROR:comment下面第二段代码中的行给出编译器警告,我不明白为什么。更让我惊讶的是,第3区的作品。

这一个工作得很好,所以我把它转换成通用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]); 
} 
+0

你为什么使用泛型? – SLaks 2012-01-06 02:15:34

+0

因为我有3个不同的版本,如果IListViewHelper 与不同类型的T. – 2012-01-06 08:19:44

由于编译器错误中明确规定,_pairDirEntry不是T,所以你不能把它传递给一个委托,需要一个T

+0

从我可以看到_pairDirEntry肯定是一个T - 这是一个PairDirEntry在这种情况下或Action1和Action3将无法正常工作。 – 2012-01-06 02:09:58

+2

@RobinLuiten:'_pairDirEntry'不能是'T',因为'T'是方法的通用参数,'_pairDirEntry'是类中的一个字段。 – SLaks 2012-01-06 02:15:24

+0

谢谢你,我一天中的大部分时间都在外面,所以只是回到这里,我不知道我现在失去了什么。如果我添加了T parm的参数并通过了它,那就没事了。我不太清楚为什么在写一篇文章到这里之前,这已经被困了2-3个小时。 – 2012-01-06 08:24:02

提供一些更详细的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不同。

这可以通过从该方法中除去的类型的参数来校正:

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

现在,行动的说法是类型相同的字段t

+0

该类没有任何其他泛型,类中只有一个泛型类型,并且该类型为该方法的类型T. – 2012-01-06 08:20:57