Why is param in this lambda expression? - mvvm

The MSDN magazine article by Josh Smith on MVVM contains a lambda expression I don't completely understand. What is the purpose of param in this code?
_saveCommand = new RelayCommand(param => this.Save(),
param => this.CanSave );
Translated to my preferred language VB it's:
Dim saveAction as New Action(Of Object)(AddressOf Me.Save)
_saveCommand = New RelayCommand(saveAction, Function(param) Me.CanSave)
I would have expected to only see param if it is used within CanSave or Save. I am somewhat new to lambda expressions. It's odd for me to see a variable that is neither declared nor used anywhere as far as I can tell. Any explanation would be appreciated.
To put this in context the constructor for RelayCommand (C#) is:
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
and in VB:
Public Sub New(ByVal execute As Action(Of Object), _
ByVal canExecute As Predicate(Of Object))

The lambda expression is declaring it - the place where it appears is basically a declaration. If it didn't, it wouldn't be compatible with Action(Of Object). That's why it's there - even though you don't actually need the value.
With anonymous methods, if you don't need any parameter values you can omit the parameter list entirely:
_saveCommand = new RelayCommand(delegate { this.Save(); },
delegate { return this.CanSave; });
... but you can't do that with lambda expressions. You have to specify the parameter list - either just as a parameter name for a single parameter, or a full list in brackets. The code you've presented is equivalent to:
_saveCommand = new RelayCommand((Object param) => this.Save(),
(Object param) => this.CanSave);

Related

Why is lambda expression used in DOTween?

I'm using a lambda expression in my C# script in my Unity project to call a function with a parameter when a DOTween callback is called.
It simply looks like this: animation.OnComplete(() => DestroyOnCompleted(children));
It works just fine, but I am note sure why a lambda expression is used in this case. I know it has something to do with delegates, but other than that, I'm not too sure; and I would like to explain it to my exam, if I get asked about it.
Could anyone enlighten me? :-)
Why not? ;)
I don't know that API too much but it seems like it is simply expecting something like
OnComplete(TweenCallback callback)
where TweenCallback from your usage basically seems to equal the c# built-in Action delegate and basically simply a parameter less void
public delegate void TweenCallback();
so whether you pass in this callback as a lambda like
animation.OnComplete(() => DestroyOnCompleted(children));
or anonymous method using the delegate operator like
animation.OnComplete(delegate { DestroyOnCompleted(children); });
or using a method
animation.OnComplete(OnCompletedAnimation);
...
private void OnCompletedAnimation()
{
DestroyOnCompleted(children);
}
is basically equivalent.
The main difference between the first two and the last one is: Where does children come from?
The lambda and delegate way allows you to pass in children from the current scope variables without having to store it in any field!
If you look at the documentation of DotTween, you see that row:
Now looking at the Source Code of DotTween, you can see the definition of TweenCallback:
public delegate void TweenCallback();
So the question now is, what is a delegate void in c#?
A delegate in c# is basically an object that "represent" a function.
But functions are not all the same, they can have parameters in input and return something (or return void).
To understand what kind of function does a delegate represent, try to just remove the keyword delegate.
For example, the TweenCallback without the keyboard delegate is:
public void TweenCaalback()
So the delegate represent a void function that has no parameters in input! (And it is Public).
What does it means represent a function?
It means that this is valid code:
void DoNothing()
{
}
TweenCallback x = DoNothing;
x();
So you can "assign functions" to a delegate that has the same function signature.
In this case, TweenCallback is a delegate void (), so you can assign to it a void() function.
What is a lambda?
A lambda is an expression of that style:
(string name, int age) => { return 3 };
you can read that as "string name and int age go in return 3"
That's a more concise way to describe that function:
int AnonymousFunction (string name, int age) {}
The main difference is that lambdas do not have any name. If you have not any parameter in input the lambda become like this:
() => {return 3;}
If you have only one statement inside the {} you are allowed to write it more shortly as
() => 3;
Final step
Is this valid code?
void DoNothing()
{
}
TweenCallback x = () => DoNothing();
Yes it is! Tween callback is expects a void () function.
() => DoNothing(); Is a lambda (un-named function) that takes nothing in input and calls some other function. It's the shorter version of () => {DoNothing();} that you have to think as void () {DoNothing();}
So when writing
animation.OnComplete(() => DestroyOnCompleted(children));
You are just passing a void () function to OnComplete Method, that makes sense because TweenCallback is a void () delegate.
Notes
As you can see, functions and lambdas expression can be converted implicitly to delegates. But you have to understand that they are all different things, and in more advanced coding scenarios that distinction is not just pure theory.

Does there exist REAL pass by reference in any language?

As far as I know there's no pass by reference in c and java essentially passes everything by value, there're dozens of stack overflow posts discussing about this.
Now I wonder that is there any example of REAL call by reference? Because during function call the value of all parameters (including pointers or mutable object identifiers) are always copied to local variables in callee's frame, in that sense everything surely passes by value.
Sure, there is. For example, C♯ has pass-by-reference. In order for pass-by-reference to occur, both the method parameter in the parameter list at the declaration site as well as the method call argument in the argument list at the call site must be annotated with the ref modifier. The same applies to Visual Basic.NET (here, the modifier is ByRef, I believe.)
C++ also has pass-by-reference, the modifier is &. PHP also has pass-by-reference and uses the same modifier. The same applies to E.
Rust also offers call-by-reference.
In contrast to all the languages listed above, where pass-by-value is the default and pass-by-reference has to be explicitly requested, Fortran II is a pass-by-reference language.
Now I wonder that is there any example of REAL call by reference? Because during function call the value of all parameters (including pointers or mutable object identifiers) are always copied to local variables in callee's frame, in that sense everything surely passes by value.
What you describe is pass-by-value. That's not pass-by-reference. With pass-by-reference, the reference itself is passed, not the value that is referenced.
Here is an example in C♯ that demonstrates pass-by-value of a value type, pass-by-value of a reference type, pass-by-reference of a value type, and pass-by-reference of a reference type:
struct MutableCell
{
public string value;
}
class Program
{
static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux)
{
foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.";
foo = new string[] { "C# is not pass-by-reference." };
bar.value = "For value types, it is *not* call-by-sharing.";
bar = new MutableCell { value = "And also not pass-by-reference." };
baz = "It also supports pass-by-reference if explicitly requested.";
qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." };
}
static void Main(string[] args)
{
var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" };
var corge = new MutableCell { value = "For value types it is pure pass-by-value." };
var grault = "This string will vanish because of pass-by-reference.";
var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." };
IsCSharpPassByValue(quux, corge, ref grault, ref garply);
Console.WriteLine(quux[0]);
// More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value.
Console.WriteLine(corge.value);
// For value types it is pure pass-by-value.
Console.WriteLine(grault);
// It also supports pass-by-reference if explicitly requested.
Console.WriteLine(garply.value);
// Pass-by-reference is supported for value types as well.
}
}

Why can't I create a callback for the List Find method in Moq?

I created an extension method that lets me treat a List as DbSet for testing purposes (actually, I found this idea in another question here on stack overflow, and it's been fairly useful). Coded as follows:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var queryable = sourceList.AsQueryable();
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider);
mockDbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression);
mockDbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
mockDbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(queryable.GetEnumerator());
mockDbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>(sourceList.Add);
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback(sourceList.Find);
return mockDbSet.Object;
}
I had been using Add for awhile, and that works perfectly. However, when I try to add the callback for Find, I get a compiler error saying that it can't convert a method group to an action. Why is sourceList.Add an Action, but sourceList.Find is a method group?
I'll admit I'm not particularly familiar with C# delegates, so it's likely I'm missing something very obvious. Thanks in advance.
The reason Add works is because the List<T>.Add method group contains a single method which takes a single argument of type T and returns void. This method has the same signature as an Action<T> which is one of the overloads of the Callback method (the one with a single generic type parameter, Callback<T>), therefore the List<T>.Add method group can be converted to an Action<T>.
With Find, you are trying to call the Callback method (as opposed to Callback<T>) which expects an Action parameter (as opposed to Action<T>). The difference here is that an Action does not take any parameters, but an Action<T> takes a single parameter of type T. The List<T>.Find method group cannot be converted to an Action because all the Find methods (there is only one anyway) take input parameters.
The following will compile:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback<Predicate<T>>(t => sourceList.Find(t));
return mockDbSet.Object;
}
Note that I have called .Callback<Predicate<T>> because the List<T>.Find method expects and argument of type Predicate. Also note I have had to write t => sourceList.Find(t) instead of sourceList.Find because Find returns a value (which means it doesn't match the signature of Action<Predicate<T>>). By writing it as a lambda expression the return value will be thrown away.
Note that although this compiles it will not actually work because the DbSet.Find method actually takes an object[] for it's parameter, not a Predicate<T>, so you will likely have to do something like this:
public static DbSet<T> AsDbSet<T>(this List<T> sourceList) where T : class
{
var mockDbSet = new Mock<DbSet<T>>();
mockDbSet.Setup(d => d.Find(It.IsAny<object[]>())).Callback<object[]>(keyValues => sourceList.Find(keyValues.Contains));
return mockDbSet.Object;
}
This last point has more to do with how to use the Moq library that how to use method groups, delegates and lambdas - there is all sorts of syntactic sugar going on with this line which is hiding what is actually relevant to the compiler and what isn't.

How to bind parameters in replaced expression nodes in Entity Framework on the fly

I'm trying to replace a function call like (simplified) Utility.GetString(MyEntity.SomePropertyWithRelatedEntity)=="abc" with an expression visitor into something like p => p.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag==true).SomePropertyWithRelatedEntity.
It means, the datamodel goes like:
MyEntity -> RelatedEntity -> SubRelatedEntity
I'm trying to return a string value from the SubRelatedEntity, based on some rules in the RelatedEntity, so I don't have to re-write / copy/paste the whole filtering rules in every usage; that's why I put inside a "call-signature", so my expression visitor can identify it and replace the fake-call to Utility.GetString to some complicated lambda expressions.
My expression visitor contains something like:
public override Expression Visit(Expression node)
{
if (node == null)
return null;
Expression result = null;
if (node.NodeType == ExpressionType.Call)
{
MethodCallExpression mce = node as MethodCallExpression;
if (mce.Method.DeclaringType == typeof(Utility) && mce.Method.Name == "GetString")
{
Expression<Func<RelatedEntity, string>> exp = re => re.SubRelatedEntities.FirstOrDefault(sre => sre.SomeFlag == true).SomeStringValue;
result = exp.Body;
}
else
result = base.Visit(node);
}
else
result = base.Visit(node);
return result;
}
Now, the problem is, the "sre" parameter is not bound when called the injected lambda expression. After much research, I see the lambda parameters should be replaced with another expression visitor, specifically searching for the new parameters and replacing them with the old ones. In my situation, however, I don't have an "old parameter" - I have the expression MyEntity.SomePropertyWithRelatedEntity (e.g. an property filled with the related entities) which I need to insert somehow in the generated lambda.
I hope my problem is understandable. Thank you for any insights!
After getting no answers for long time and trying hard to find a solution, I've solved it at the end :o)! It goes like this:
The newly injected lambda expression gets an ParameterExpression - well, this is a 'helper', used when directly calling the lambda, what I don't want (hence, 'parameter not bound' exception when ToEnumerable is called). So, the clue is to make a specialized ExpressionVisitor, which replaces this helper with the original expression, which is of course available in the Arguments[] for the method call, which I try to replace.
Works like a charm, like this you can reuse the same LINQ expressions, something like reusable sub-queries, instead of writing all the same LINQ stuff all time. Notice as well, that expression calling a method is not allowed in EF, in Linq2Sql it worked. Also, all the proposed web articles only replace the parameter instances, when constructing/merging more LINQ expressions together - here, I needed to replace a parameter with an faked-method-call argument, e.g. the method should not be called, it only stands for a code-marker, where I need to put my LINQ sub-query.
Hope this helps somebody, at the end it's pretty simple and logical, when one knows how the expression trees are constructed ;-).
Bye,
Andrej

Why do I get a lambda error that no-one else gets?

I'm trying to debug the following line:
MOrigValue.AllInstances.TestString = () => "New value";
There's a red squiggly line under:
() => "New value";
Mouseover shows the following error:
Delegate 'Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue, string>' does not take 0 arguments
Here is the complete class:
namespace OrigValueP
{
public class OrigValue
{
public string TestString() { return "Original value"; }
}
}
Here's the info from the object browser.
Click on the property MOrigValue.AllInstances.TestString:
public static Microsoft.Moles.Framework.MolesDelegates.Func<OrigValueP.OrigValue,string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue.AllInstances
So, to a non-techie like me, that would explain the red squiggly line error above..
Click on the property MOrigValue..TestString:
public Microsoft.Moles.Framework.MolesDelegates.Func<string> TestString { set; }
Member of OrigValueP.Moles.MOrigValue
To me, this looks like the definition that I would have expected to see for MOrigValue.AllInstances.TestString. In other words a property that is actually a Moled "method" that has no parameters and returns a string.
As an experiment, based on the first object browser info above, I inserted the class as an input parameter, as follows:
MOrigValue.AllInstances.TestString = (OrigValue) => "New value";
This works :)
But my workaround looks like a "hack". I've seen every page on the internet (including StackOverflow) relating to moles and how to remove them painlessly. Many of them have lines with a lambda similar to the following:
MMyClass.AllInstances.DoSomething = () => "Hello world";
Assert.AreEqual("Hello world", new MyClass().DoSomething());
The fundamental issue is that Moles started from a method that takes no parameters and returns a string. The Moled equivalent takes its own class as a parameter and returns a string. Surely Moles knows that TestString() is a member of OrigValue.
Maybe my problem is a result of using VS Express, rather than the paid versions. I can live with that, but it would still be interesting to know why I need the hack. There might be cases where the hack produces incorrect test results without my knowledge.
BTW: I think this example proves the value of the object browser.
Your expectation is wrong. The "hack" you describe is the official documented way to use the AllInstances nested type. Its delegates really do always take a parameter containing an instance of the type under test.
It is unlikely that you could have seen this form of usage of AllInstances
MMyClass.AllInstances.DoSomething = () => "Hello world";
which, if you have, could be a mistake made by the author of the code.
What you expect to be the definition of a delegate belonging to the AllInstances type is really a different kind of use of Moles: it's used to detour an instance method of a single instance.
The "Mole Basics" section of the document "Microsoft Moles Reference Manual" contains more information on the topic. Here is an excerpt from there.
Instance Methods (for One Instance)
... The properties to set up those moles are instance methods of the mole type itself. Each instantiated mole type is also associated with a raw instance of a moled method type.
For example, given a class MyClass with an instance method MyMethod:
public class MyClass {
public int MyMethod() {
...
}
}
We can set up two mole types of MyMethod such that the first one always returns 5 and the second always returns 10:
var myClass1 = new MMyClass() { MyMethod = () => 5 };
var myClass2 = new MMyClass() { MyMethod = () => 10 };