Reputation: 5328
I don't think its a Rhino mocks related.
Is it a compiler bug ?
The line in 2nd block of code below the ERROR: comment is giving the compiler warning, and I dont understand why. What surprised me even more was that block 3 works.
This one works fine, so i converted it to 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()
}
This one works fails to compile on commented line
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()
}
This change to the generic works fine.
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]);
}
Upvotes: 1
Views: 3617
Reputation: 43056
To provide some more detail to SLaks's answer, consider this class:
class C<T>
{
private T t; //assume that this gets assigned somehow
private void M<T>(Action<T> action)
{
action(this.t);
}
}
That won't compile because the T
parameter of the method hides the T
parameter of the class. They do not refer to the same type, even though they have the same name. The type of the action's argument is not the same type as the field t
.
This can be corrected by removing the type parameter from the method:
class C<T>
{
private T t; //assume that this gets assigned somehow
private void M(Action<T> action)
{
action(this.t);
}
}
Now, the action's argument is of the same type as the field t
.
Upvotes: 2
Reputation: 888107
As the compiler error clearly states, _pairDirEntry
isn't a T
, so you can't pass it to a delegate that takes a T
.
Upvotes: 2