C# Closure binding - c#

Given the following, when is foo bound?
System.Timer t = new System.Timer( (a)=>{
var foo = Messages.SelectedItem as FooBar;
});
Is it bound then the anonymous method is executed, or when the method is defined?

foo is not bound at all, as it's internal to the anonymous method. It will call Messages.SelectedItem. If Messages is an instance property, what is bound is the 'this' instance, which is used to get at Messages.

Never, because of the compile-time error you would get due the absence of a System.Timer class in the BCL. Assuming you wanted a System.Threading.Timer then the closure will be bound/captured at the moment this constructor is called i.e. the method is defined. If you want to bind it when the method is executed you need another constructor overload and pass a state.
var t = new System.Threading.Timer(a =>
{
var foo = a as FooBar;
}, Messages.SelectedItem, -1, -1);
Now when the callback runs it will use the Messages.SelectedItem value at the moment this callback executes.

Related

How are methods with arguments invoked?

I am trying to call a method with arguments, but it doesn't work. I have this method:
public class AllMethods
{
//method change state and status of entity objetivovisitacao for "Propagado"
public static void changeStatus(Guid objetivoId, IOrganizationService service, int state)
{
SetStateRequest setStateRequest = new SetStateRequest
{
EntityMoniker = new EntityReference("statuscode", objetivoId),
State = new OptionSetValue(0),
Status = new OptionSetValue(911950001),
};
service.Execute(setStateRequest);
}
}
And I need to call that method, so I tried doing it this way:
AllMethods.changeStatus();
But it's wrong. Can someone explain this so that I can better understand what I'm missing here?
First create variables for the parameters of the method. Then pass them in the same order as they was declared in the method.
Guid yourObjetivoId = new Guid();
IOrganizationService yourService = New YourImplementationOfOrganizationService();
int yourState = 3;
AllMethods.changeStatus(yourObjetivoId, yourService, yourState);
From MSDN: Methods (C# Programming Guide)
The method definition specifies the names and types of any parameters
that are required.
When calling code calls the method, it provides
concrete values called arguments for each parameter.
The arguments
must be compatible with the parameter type but the argument name (if
any) used in the calling code does not have to be the same as the
parameter named defined in the method
No need to state the types of the parameters when passing them through.
You should call it like this:
AllMethods.changeStatus(objetivoId, service, state);
you need to pass the parameters, see documentation: Pass parameters c#
in your case
AllMethods.changeStatus(objetivoId, service, state);
If you declare a method like you did:
public static void changeStatus(Guid objetivoId, IOrganizationService service, int state)
you declare parameters in the parentheses. The compiler expects the necessary input when you try to call it. So you need the fitting parameters for the call of this method. It is like a key to a lock.
Guid objetivoId = // your value
IOrganizationService service = // your value
int state = // your value
then you call it like this:
AllMethods.changeStatus(objetivoId, service, state);
You don't need to declare them again in the call! it has to be done beforehand
You are doing it wrong since, you are declaring the types of the parameter here:
AllMethods.changeStatus(Guid objetivoId, IOrganizationService service, int state);
for calling this method changeStatus(...), you need to pass the variable for the parameters objetivoId, service, state.
AllMethods.changeStatus(objetivoId, service, state);
See: Passing of Parameters in C#
MSDN:
In C#, arguments can be passed to parameters either by value or by
reference.

Setting up moq and verifying that a method was called

Using Microsoft Test Framework and Moq I'm trying to verify if a log4net method was called.
[TestMethod()]
public void Log_Info_When_Stuff_Is_Done()
{
SampleClass sampleObject = new SampleClass();
Mock<log4net.ILog> logMockObject = new Mock<log4net.ILog>();
sampleObject.Log = logMockObject.Object;
sampleObject.DoStuffAndLogInfo();
logMockObject.Verify(moqLog => moqLog.Info("do stuff got called"), Times.AtLeastOnce());
}
I get an exception on Verify call saying that
Expected invocation on the mock at least once, but was never
performed: moqLog => moqLog.Info("do stuff got called") No setups
configured. No invocations performed.
What am I doing wrong?
update the problem was with a getter for SampleClas.Log property. I was always returning LogManager.GetLogger(...); even when the property was already set to a ILogProxy. I was under impression that the property's get accessor won't be called because I've set up a proxy like so sampleObject.Log = logMockObject.Object;
Right now Moq is verifying that DoStuffAndLogInfo calls Info with the exact string "do stuff got called". If it's actually calling Info with a different argument, and you don't care what the actual argument is, use the following instead:
logMockObject.Verify(moqLog => moqLog.Info(It.IsAny<string>()), Times.AtLeastOnce());
The test is correctly set up.
Check your sut to see if Log.Info actually gets called inside the DoStuffAndLogInfo method.
This doesn't look to be the original poster's problem, but in my case I had a very similar error message. It was due to my .Verify() call before the actual execution. For example, this is wrong:
SampleClass sampleObject = new SampleClass();
Mock<log4net.ILog> logMockObject = new Mock<log4net.ILog>();
logMockObject.Verify(moqLog => moqLog.Info(It.IsAny<string>()), Times.AtLeastOnce());
sampleObject.Log = logMockObject.Object;
sampleObject.DoStuffAndLogInfo();
....but this is right:
SampleClass sampleObject = new SampleClass();
Mock<log4net.ILog> logMockObject = new Mock<log4net.ILog>();
sampleObject.Log = logMockObject.Object;
sampleObject.DoStuffAndLogInfo();
logMockObject.Verify(moqLog => moqLog.Info(It.IsAny<string>()), Times.AtLeastOnce());

C# compiler oddity with delegate constructors

Based on the following question, I found some odd behaviour of the c# compiler.
The following is valid C#:
static void K() {}
static void Main()
{
var k = new Action(new Action(new Action(K))));
}
What I do find strange is the compiler 'deconstructing' the passed delegate.
The ILSpy output is as follows:
new Action(new Action(new Action(null, ldftn(K)), ldftn(Invoke)).Invoke);
As one can see, it automatically decides to use the Invoke method of the delegate. But why?
As it is, the code is unclear. Do we have a triply-wrapped delegate (actual) or is the inner delegate just 'copied' to the outer ones (my initial thought).
Surely if the intent was like the compiler emitted the code, one should have written:
var k = new Action(new Action(new Action(K).Invoke).Invoke);
Similar to the decompiled code.
Can anyone justify the reason for this 'surprising' transformation?
Update:
I can only think of one possible use-case for this; delegate type conversion. Eg:
delegate void Baz();
delegate void Bar();
...
var k = new Baz(new Bar( new Action (K)));
Perhaps the compiler should emit a warning if the same delegate types are used.
The spec (section 7.6.10.5) says:
The new delegate instance is initialized with the same invocation list as the delegate instance given by E.
Now suppose the compiler translated it to something similar to your suggestion of:
new Action( a.Target, a.Method)
That would only ever create a delegate with an invocation list of a single method call. For a multi-cast delegate, it would violate the spec.
Sample code:
using System;
class Program
{
static void Main(string[] args)
{
Action first = () => Console.WriteLine("First");
Action second = () => Console.WriteLine("Second");
Action both = first + second;
Action wrapped1 =
(Action) Delegate.CreateDelegate(typeof(Action),
both.Target, both.Method);
Action wrapped2 = new Action(both);
Console.WriteLine("Calling wrapped1:");
wrapped1();
Console.WriteLine("Calling wrapped2:");
wrapped2();
}
}
Output:
Calling wrapped1:
Second
Calling wrapped2:
First
Second
As you can see, the real behaviour of the compiler matches the spec - your suggested behaviour doesn't.
This is partly due to the somewhat odd "sometimes single-cast, sometimes multi-cast" nature of Delegate, of course...
When you try to treat a delegate as a method, the compiler actually uses the delegate's Invoke() method. So, for example, the two lines below compile to the exact same IL (both call Invoke()):
k();
k.Invoke();
I assume the oddity you're seeing is a consequence of this. The delegate constructor expects a method (or rather, a method group), but it gets a delegate instead. So it treats it as a method and uses the Invoke() method.
As for the meaning, it is delegate that calls delegate that calls the actual method. You can verify this yourself by accessing the delegate's Method and Target properties. In the case of the outer-most delegate, Method is Action.Invoke and Target the inner delegate.
delegate is a class
Action delegate has a constructor like so
public extern Action(object #object, IntPtr method);
Since K is a static method there is no need to pass object to inner most action instance as first argument and hence it passes null
Since second argument is pointer to function therefore it passes pointer of K method using ldftn function
for the remaining Action instances the object is passed is inner Action and the second parameter is the Invoke method since when you call a delegate you're actually calling the Invoke method
Summary
var action = new Action(K) => Action action = new Action(null, ldftn(K))
new Action(action) => new Action(action, ldftn(Action.Invoke))
I hope this explains what is happening?

Moling DataContext with MS Moles?

How can I mole the DataContext that I'm using in a class to write messages to a table. I'd like to assert that the table LINQ is writing to has the expected count of messages. Here's what i have so far.
var context = new MJustTestingDataContext();
MyMessagewriter writer = new MyMessageWriter(context);
var messageList = new List<MIncmoingMessage>();
MTable<MIncomingMessage> messageTable = new MTable<MIncomingMessage>();
messageTable.Bind(messagesLinqList.AsQueryable());
If I use this code with xUnit in my class under test I'll get this exception
Microsoft.Moles.Framework.Moles.MoleNotImplementedException: DataContext.Dispose() was not moled.
What am I missing here and how to implement DataContext.Dispose() on the mole? I'm using moles standalone without Pex.
When you create a new Mole the default behavior for its methods and properties is to throw a MoleNotImplementedException whenever they are called.
To implement the mole you can do context.Dispose = () => {}; which means that nothing happens when the Dispose method gets called on the moled instance.
I reread the question and you probably are having a problem since Dispose is defined in a base class. To mole base method you need to do the following:
var context = new MJustTestingDataContext();
var baseContext = new MDataContext(context);
baseContext.Dispose = () => {};
You'll need to implement every property/method that gets called by the code under test or you can set the default behavior for the mole instance globally using the method BehaveAsDefaultValue. This way every method in the mole will do nothing and return the default value for it's return type if one exists instead of throwing a MoleNotImplementedException. However if you require this behavior it's better to use a stub than a mole.
I'm having trouble understanding what your test is doing. I had to do something similar yesterday, so I'll share my experience. First, it's important to understand that you don't need to use all the MoleTypes to test your code -- you just need to use Moles to redirect certain parts of your code to lambda expressions. Given a method that does this:
get a list of users to modify from the database
modify every user in the set
send the new set back to the database
I'd like to redirect 1 and 3 to not use the database. For instance, I can redirect the call to SubmitChanges (3) via this code:
bool hitSubmitChanges = false;
int changeCount = 0;
IList<object> updates = null;
// more code here...
// redirect DataContext.SubmitChanges() to a lambda to catch updates
MDataContext.AllInstances.SubmitChanges = (c) =>
{
changeCount = c.GetChangeSet().Updates.Count;
updates = c.GetChangeSet().Updates;
hitSubmitChanges = true;
};
That (and the call to get the users) would be the only Moletypes I'd use in the test. The rest of it would be normal. Then I can use assertions to check the values of changeCount, updates and hitSubmitChanges.

Redirect method call within delegate

I have a protected method in a base class which accepts a Func<T> and then turns around and executes with some added goodness. Example usage:
public MyResponse DoSomething(MyRequest request)
{
return base.Execute(() => this.Channel.DoSomething(request));
}
What I'm looking to do is take the func delegate instance and redirect the method call in the expression to another instance besides this.Channel, so something like:
protected TResponse Execute<TResponse>(Func<TResponse> command)
{
return command.Method.Invoke(this.otherInstanceOfChannel, command.Target);
}
Here the "this.otherInstanceOfChannel" would be an instance of a different concrete class than the "this.channel" passed in the original call but implements the same interface. I just need to figure out what method is being called and execute that on another instance passing in the original arguments from the caller. I started down the path of MethodCallExpressions and the like but my expression-foo is weak...
Edited/rewrote for clarity - hope this version makes more sense.
Thanks,
Matt
Yes you can do this. No time right now to give you the full solution but here is a skeleton of what you would do:
protected TResponse Execute<TResponse>(Expression<Func<TResponse>> command)
{
// Check that the expression is in the correct format (ie you are calling a method off of a type Channel
// Get the name of the method call. Something like:
var node = expr.Body as MemberExpression;
if (object.ReferenceEquals(null, node))
throw new InvalidOperationException("Expression must be of member access");
var methodName = node.Member.Name;
// Use reflection to invoke methodName on otherInstanceOfChannel
// Cast the results to TResponse and return
}
As you can see the only real trick is the use of Expression<>. The type change is transparent to any client code - they don't have to change at all. Here is some code to get you started with parsing expression trees.
I believe that you can provide the instance in the lambda expression like so:
IMyChannel myChannelInstance = MyChannelInstanceFactory.Create();
Execute(() => myChannelInstance.DoSomething(request))
If this can not be done with lambda expressions and I am sure they can you can change this to a delegate and it would work fine. The lambda expression is pointing to a code execution block and as such you can put whatever matches the expression arguments in that code block.

Categories