views:

5699

answers:

4

I am new to all the anonymous features and need some help. I have gotten the following to work:

 public void FakeSaveWithMessage(Transaction t) {
  t.Message = "I drink goats blood";
 }
 public delegate void FakeSave(Transaction t);
 public void SampleTestFunction() {
  ...
  Expect.Call(delegate { _dao.Save(t); }).Do(new FakeSave(FakeSaveWithMessage));
  ...
 }

But this is totally ugly and I would like to have the inside of the Do to be an anonymous method or even a lambda if it is possible. I tried:

Expect.Call(delegate { _dao.Save(t); }).Do(delegate(Transaction t2) { t2.Message = "I drink goats blood"; });

and

Expect.Call(delegate { _dao.Save(t); }).Do(delegate { t.Message = "I drink goats blood"; });

but these give me

Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type compile errors.

What am I doing wrong?


Because of what Mark Ingram posted, seems like the best answer, though nobody's explicitly said it, is to do this:

public delegate void FakeSave(Transaction t);
...
Expect.Call(delegate { _dao.Save(t); }).Do( new FakeSave(delegate(Transaction t2) { t.Message = expected_msg; }));
A: 

Try something like:

Expect.Call(delegate { _dao.Save(t); }).Do(new EventHandler(delegate(Transaction t2) { t2.CheckInInfo.CheckInMessage = "I drink goats blood"; }));

Note the added EventHandler around the delegate.

EDIT: might not work since the function signatures of EventHandler and the delegate are not the same... The solution you added to the bottom of your question may be the only way.

Alternately, you could create a generic delegate type:

public delegate void UnitTestingDelegate<T>(T thing);

So that the delegate is not Transaction specific.

Chris Marasti-Georg
+7  A: 

That's a well known error message:

http://staceyw.spaces.live.com/blog/cns!F4A38E96E598161E!1042.entry

Basically you just need to put a cast in front of your anonymous delegate (your lambda expression).

Mark Ingram
+2  A: 

What Mark said.

The problem is that Do takes a Delegate parameter. The compiler can't convert the anonymous methods to Delegate, only a "delegate type" i.e. a concrete type derived from Delegate.

If that Do function had took Action<>, Action<,> ... etc. overloads, you wouldn't need the cast.

hwiechers
A: 

The problem is not with your delegate definition, it's that the parameter of the Do() method is of type System.Delegate, and the compiler generated delegate type (FakeSave) does not implicitly convert to System.Delegate.

Try adding a cast in front of your anonymous delegate:

Expect.Call(delegate { _dao.Save(t); }).Do((Delegate)delegate { t.Message = "I drink goats blood"; });
Brannon
This doesn't work delegate {} is an anonymous function - it is not a type. System.Delegate is the abstract base class that is the implicit base of all delegate types declared. There's really 3 different uses of the word delegate here! You can downcast any delegate type (such as EvantHandler, Action, Func<R>) to Delegate but you have to actually create a delegate type first!
George Mauer