Does `this.SomeMethod` passed as Func argument capture `this`? - c#

If a method asks for some Func:
void Foo(Func<string> stringFactory);
Then passing a lambda referencing this introduces variable capturing:
Foo(() => this.MagicStringProperty); // Captures `this`
Does this happen also when passing an instance method instead of a lambda?
Foo(this.GetMagicString); // Capturing??
string GetMagicString()
{
return "Bar";
}
If so, is this compiled to a similar thing as the lambda version?
If not, how does it manage to pass both the method (which exists somewhere) and the instance (which exists somewhere else)?

this doesn't have to be captured in a closure here. The difference between the calls is that there is a compiler generated method for () => this.MagicStringProperty(). This method simply calls this.GetMagicString().
If you decompile the code you will see that Foo(this.GetMagicString) translates to this.Foo(new Func<string>((object) this, __methodptr(GetMagicString))) and that Foo(() => this.GetMagicString()) translates to this.Foo(new Func<string>((object) this, __methodptr(<.ctor>b__1_0))) where <.ctor>b__1_0 is the compiler generated method that calls this.GetMagicString():
[CompilerGenerated]
private string <.ctor>b__1_0()
{
return this.GetMagicString();
}

Related

Method group behaving differently than lambda?

I am using Moq to mock some interface. Here it is:
var titleGenerator = new Mock<ITitleGenerator>();
titleGenerator.Setup(t => t.GenerateTitle()).Returns(Guid.NewGuid().ToString);
Console.WriteLine(titleGenerator.Object.GenerateTitle());
Console.WriteLine(titleGenerator.Object.GenerateTitle());
It prints the same value twice. But if I replace the second line with this:
titleGenerator.Setup(t => t.GenerateTitle()).Returns(() => Guid.NewGuid().ToString());
it returns unique values on each call.
I always thought method groups are just a shortcut to lambda expression. Is there any difference? I tried searching the documentations for any explanation. Can someone enlighten me?
It looks like the method group evaluates the expression once and somehow caches it? Or does it have something to do with Moq?
In your first example, you're passing the ToString function of a single Guid, which then gets called on every invocation. It's equivalent to this:
Guid guid = Guid.NewGuid();
titleGenerator.Setup(t => t.GenerateTitle()).Returns(guid.ToString)
In your second example, you're passing a function that first creates a new Guid and then invokes ToString() on it.
The difference is in the inputs. In the first case the "method group" is actually a delegate for Guid.ToString. But since it requires an instance as "input", the instance is part of the delegate expression, and so the same "input" is used each time.
It would be equivalent to:
var titleGenerator = new Mock<ITitleGenerator>();
Guid g = Guid.NewGuid();
titleGenerator.Setup(t => t.GenerateTitle()).Returns(g.ToString);
In the second case, the delegate has no input. The Guid instance is calculated within the delegate, so a new Guid is used each time.
For an equivalent example that might be easier to understand, the code:
var id = 1;
Func<string> f = id.ToString;
id = 2;
Console.WriteLine(f()); // 1
will write "1", whereas:
var id = 1;
Func<string> f = () => id.ToString();
id = 2;
Console.WriteLine(f()); // 2
will write "2".
In the first case, the delegate (Func<> instance) f is created with the value 1 as Target and the method info for string int.ToString() as Method. The later reassignment to id does not affect f.
In the second case, things will be more indirect. The compiler will generate a new method that corresponds to the => arrow. The local variable id is captured or closed over (is in the closure of the lambda). That means, behind the scenes, id is really promoted to a field somewhere (compiler's choice). When your method mentions id, it really accesses that field. And the compiler-generated method corresponding to the => arrow also reads that field. Now the Func<> is created with its Method property being this compiler-generated method. Because of all this, the result will be "2" here. That is the closure semantics of anonymous functions in C#.
Your original Moq example is just the same. The Returns overload in question takes an argument Func<TResult> valueFunction where TResult is string in your use. That valueFunction is what I called f in my simpler example.

How to stub a method with out parameter using custom delegate?

I am trying to stub a method that has an out paramteter using RhinoMock's Do method, but I keep getting the message cannot resolve symbol outParam. Here's the stubbing part:
private static void FakeClientsLoading(MyClass fakeClass, IEnumerable<string> clientsToLoad)
{
fakeClass.Stub(
x =>
x.LoadClientsFromDb(Arg<string>.Is.Anything,
out Arg<object>.Out(null).Dummy))
.Do(
new LoadClientsFromDbAction(
(someString, out outParam ) =>
TestHelper.LoadClients(someString, clientsToLoad)));
}
And here is my custom delegate declaration:
public delegate void LoadClientsFromDbAction(string s, out object outParam);
What I'd like to achieve is to run the test helper method whenever LoadClientsFromDb is invoked. From my understanding outParam should be mapped to whatever is passed as the out parameter to the called method, but it doesn't seem to work this way.
It seems that I have finally found the answer to my question. It turns out that, quoting section 26.3.1 from this link:
Specifically, a delegate type D is compatible with an anonymous method
or lambda-expression L provided:
If L is a lambda expression that has an implicitly typed parameter list, D has no ref or out parameters.
This means that you need an explicitly typed parameter list in order to create a lambda with an out parameter.
That's not all, though. It is still necessary to assign a value to the out parameter upon exiting the anonymous method.
The final and working code:
private static void FakeClientsLoading(MyClass fakeClass, IEnumerable<string> clientsToLoad)
{
fakeClass.Stub(
x =>
x.LoadClientsFromDb(Arg<string>.Is.Anything,
out Arg<object>.Out(null).Dummy))
.Do(
new LoadClientsFromDbAction(
(string someString, out object outParam) =>
{
outParam = null;
TestHelper.LoadClients(someString, clientsToLoad);
}
));
}

Extension method on lambda expression

I have a helper method which gets the name of a property defined by a lambda which works as below:
ExpressionUtil.GetName((Thing t) => t.Property); // returns "Property"
I would like to turn this into an extension method so the syntax would be of the form:
((Thing t) => t.Property).GetName(); // wont compile : operator '.' cannot be applies to operand of type 'lambda expression'
However I cant seem to do this as ((Thing t) => t.Property) is a lambda (not an expression or Func yet). Is there any way to write an extension method which applies directly to a lambda? If not why is this a bad thing to do?
You can't do that, because a lambda expression has no type by itself; its type is determined by the context (e.g. if you assign it to a delegate variable or pass it as an argument to a method).
Since ((Thing t) => t.Property) doesn't have a type, you can't call an extension method on it, because the compiler doesn't know which extension methods are valid candidates.
You can, however, declare a variable and call the extension method on it:
Func<Thing, OtherThing> func = t => t.Property;
string name = func.GetName();
you may create an extension method on an Action at the low cost of having a introducing instantiation.
I sometimes use it and the code is readable.
The reason this code exists is less elegant, a rotten NAS :-[
new Action(() =>
{
if (File.Exists(newFullPath))
File.Delete(newFullPath);
File.Move(oldFullPath, newFullPath);
})
.Try(attemps: 2, exceptionValidator: (exception, attempt, attempts) =>
{
var throwIt = (attempt == attempts);
if (!throwIt)
Thread.Sleep(500);
// .. tracing ./. throw
return (throwIt);
});
Just in case ... even if post not young.

What does this mean in C# or LINQ? - ( () => )

I was going through Jeffrey Palermo's book and came across this syntax.
private void InitializeRepositories()
{
Func<IVisitorRepository> builder = () => new VisitorRepository();
VisitorRepositoryFactory.RepositoryBuilder = builder;
}
What does it mean?
() => indicates a lambda expression that takes no arguments.
In general, it means a function with no arguments.
In this particular example, it creates an anonymous function with no arguments that returns a new VisitorRepository(); object every time.
Func<IVisitorRepository> stands for a delegate which takes no arguments and returns a IVisitorRepository. The creation of that delegate is a lambda function:
() //means no parameters
=> new VisitorRepository()// means it returns a new VisitorRepository
() is the place where you place your variables
Example a common event handled would look like (sender, args)
=> // means throw these parameter into this method
after => you can either drop a one line execution thing like new VisitorRepositor()
OR
you can place a whole function like
Func<IRepository> = (sender, args) =>
{
var myObject = (SomeObject)sender;
return new VisitorReposiroty { id = myObject.SomeId };
}
As other stated it's lambda expression and it really clears your code from method or function that handle a specific event.
Once you read them good it's really damn useful.
The () => syntax is a lambda expression. Lambdas were introduced in C# 3.0 and are used to define an anonymous method for a delegate.
The delegate is defined using the generic Func. So in this case the signature for the delegate is: no input parameters and one output parameter of type IVisitorRepository.
So on the left side of the => lambda array are the names of the input parameters. In case of no input parameters just write (). On the rightside of the => lambda is the code to return the output parameter, in this example: new VisitorRepository().
I suggest read more about lambda expressions in C# to fully understand this code. There is also a generic delegate involved, so you need understanding of Generics and Delegates as well.
Func is a delegate without parmeter and with an IVisitorRepository return value.
() => is a lambda expression creating an anonymous method.
new VisitorRepository() is the content of this anonymous method.
so this line is creating a delegate which is pointing to a anonymous method, which is returning an instance of VisitorRepository.
Func<IVisitorRepository> builder = () => new VisitorRepository()
In the next line, you set the value of a static property to this just created delegate.
VisitorRepositoryFactory.RepositoryBuilder = builder;
After this you can use the property to call the anonymous method, which is creating a new instance of VisitorRepository.
IVisitorRepository repository = VisitorRepositoryFactory.RepositoryBuilder();
In this case, repository will be an instance of VisitorRepository.
It means a function takes no parameters, like:
delegate() {//}

What is the name for this usage of delegate in C#?

This is a terminology question. In C#, I can do this:
delegate Stream StreamOpenerDelegate(String name);
void WorkMethod(StreamOpenerDelegate d)
{
// ...
}
void Exec1()
{
WorkMethod((x) =>
{
return File.OpenRead(x);
});
}
void Exec2()
{
StreamOpenerDelegate opener = (x) =>
{
return File.OpenRead(x);
};
WorkMethod(opener);
}
Q1
The Exec1() method demonstrates the use of an anonymous delegate, correct?
Q2
Inside Exec2(), would opener
be considered an anonymous delegate? It does have a name. If it's not an anonymous delegate, what should I call it? Is there a name for this syntax? "named anonymous delegate?" a local variable holding an anonymous delegate?
Q1: There's no such term as "anonymous delegate" (in the C# language specification) - but this uses a lambda expression which is one kind of anonymous function. See section 7.14 of the C# language specification for details.
Q2: opener is a variable. The variable is assigned a value created using a lambda expression. After it's been created, the delegate is just an instance of StreamOpenerDelegate. In other words, the concepts of lambda expression, anonymous function and anonymous method are source code concepts rather than execution time concepts. The CLR doesn't care how you created the delegate.
By the way, both of your lambda expressions can be expressed more concisely - fewer parentheses etc:
void Exec1()
{
WorkMethod(x => File.OpenRead(x));
}
void Exec2()
{
StreamOpenerDelegate opener = x => File.OpenRead(x);
WorkMethod(opener);
}
alternatively you could just use a method group conversion:
StreamOpenerDelegate opener = File.OpenRead;
No and no.
A1: This feature is new to C# 3.0 and is called a lambda expression. C# 2.0 has a similar feature called anonymous methods; for example:
button.Click += delegate {
//code
};
A2: opener is a regular variable that happens to hold a lambda expression.
By the way, a lambda expression that takes exactly one parameter doesn't need parentheses. Also, a lambda expression that consists only of a return statement doesn't need braces.
For example:
StreamOpenerDelegate opener = x => File.OpenRead(x);

Categories

Resources