I recently noticed the following code which basically defines a class method
public Func<string, string> SampleMethod = inputParam =>
{
return inputParam.ToUpper();
};
which is the same as doing it in the old fashioned way
public string SampleMethod(string inputParam )
{
return inputParam.ToUpper();
}
My question - why would I prefer the first over the second? My eyes are maybe more trained to understand the second style quicker. I find it similar to the difference between SMS lingo and plain old english.
Those two things are fundamentally different. The former is a field of a delegate type while the latter is really a method. The tiniest difference I can think of is that you can modify the first one dynamically at runtime and assign another method reference to it while the second is fixed.
You shouldn't normally prefer the first over the second if your purpose is to write a simple method for a class in C#.
An example that makes the first extremely fragile:
var c = new SomeClass();
c.SampleMethod = inputParam => inputParam.ToLower();
c.DoSomeTaskThatReliesOnSampleMethodReturningAnUpperCaseString();
c.SampleMethod = null;
c.DoSomeTaskThatCallsSampleMethod(); // NullReferenceException
This style of programming is common in language like Javascript where an object is fundamentally a dynamic creature built upon a simple dictionary.
They are actually not the same at all. The second is a regular member method, that returns ToUpper on the input string.
The first, on the other hand, is a Func member variable, that happens to point to a delegate, that implements the same functionality. However, as this is a method pointer, you can substitute the delegate with any other delegate of the same type at runtime. I.e. you can completely redefine what it means to call this method.
One benefit of the second way is it's better from a unit testing perspective - you can test your class and know that the method will correctly return the uppercase string. With the first method, you can change the method at runtime, so unit testing is much harder.
Related
For a test, I want to create a generic "helper" method which will take take two arguments, the first argument is a function (or a reference to the function) and the 2nd argument is a list of objects for that function that are to be called as its parameters.
The following does this perfectly:
CallMyFunctionWithParamsPlease(new Func<int, int>(MyMethod), new object[] {1});
public static int CallMyFunctionWithParamsPlease(Delegate func, params object[] args)
{
func.DynamicInvoke(args);
return 3;
}
The thing is, this doesn't look very nice when calling it and I wish to abstract it into another method to act as syntatic sugar.
Ideally I want it to be called like this:
CallMyFunctionWithParamsPlease(myMethod, new Object[] {1});
From what I can gather, there is no elegant solution to do this in C# since I cannot pass myMethod by itself as a reference anywhere, instead I must pass it by declaring a new Func along with the return type of the method. Since I'm not using this return type anywhere, I'm not sure why it's necessary to input this information. My limited understanding is that because C# is statically typed, the compiler must know everything and things like this just aren't possible.
Is this true or not? How would I create syntatic sugar to simply pass a method to another method which can be called there without needing to invoke "new Func"? I would have thought simply passing the function as a reference pointer would allow me to do this, but I'm having difficultly doing this too. I looked into delegates, using "unsafe" with pointers, and a few other options. None of them seem to make this possible, or if they do, they didn't explain it in a manner that I could understand.
I simply want to pass a method to another method, and invoke it with a variable list of object params with variable length whereby I don't need to specify this whilst invoking it. I'm not sure if I'm trying to force C# to do something it's not meant to do here, and instead I'd be better off using a dynamically typed language to do this. The problem is I really enjoy the intellisense that the static typing of C# offers, along with the performance improvements over a language like Python. I'd just like a way to syntactically abstract away the boilerplate with my own helper methods for things like this.
UPDATE: Thanks to the comments here it seems I can do this with a lambda expression nice and elegantly. The signature can be simply changed to public static long CallMyFunctionWithParamsPlease<T>(Func<T> func)
If deferred execution is what you want simply pass a Func<TReturnType> to your method (or class). The calling method doesn't need to know how many parameters are involved.
e.g. Assuming MyMethod has a signature int MyMethod(int arg):
CallMyFunctionWithParamsPlease(() => MyMethod(1));
public static int CallMyFunctionWithParamsPlease(Func<int> func)
{
return func();
}
If MyMethod takes two parameters, it's the same call:
CallMyFunctionWithParamsPlease(() => MyMethod(1, 2));
I'm curious to understand what's happening behind the scenes in a situation like this:
public static void OuterMethod() {
// some random code
var a = 42;
var b = "meaning of life";
Func<string, object> factory = (aString) {
// do something with a and b
return "Hello World";
};
// some more random code
factory("My string");
}
I'm particularly interested in cases where OuterMethod is called very often. In my case it's the MVC request pipeline where OuterMethod is called once for each request.
Am I incurring a lot overhead by having to build factory each time the method is called? I could easily move the Func outside of OuterMethod into its own static method however in my actual scenario because it is defined inside I have access to a lot of variables I need to do my calculation that I would otherwise need to include in the signature of a method defined outside. Maybe this is just a micro optimization but I would like to better understand how the compiler treats these kinds of statements.
The actual lambda is going to result in a new named method (you just don't know what that name is) being created at compile time (the exact semantics will vary based on some of the specifics).
The only work being done on each invocation of the method is the creation of a new delegate object that has its own pointer to the same named method. If constructing that one object instance is really too much for you (hint: its not) then you could save that work by extracting the delegate out of the method.
I'm trying to use delegates to cut down on my code in this project.
I have 4 DropDownLists in my asp.net page. In my codebehind file I'm binding them to different business object calls with data. Right now I have the following code:
DeptList.DataSource = bl.getAcademicDepts();
DeptList.DataBind();
TermList.DataSource = bl.getTerms();
TermList.DataBind();
InstructorList.DataSource = bl.getInstructors();
InstructorList.DataBind();
EEList.DataSource = bl.getEE();
EEList.DataBind();
This seems really repetitive so I decided to make a function as a shortcut
private void SourceAndBind(DropDownList d, <business layer method call>)
{
d.DataSource = <businesslayer method call>();
d.DataBind();
}
Then my first block of code simply becomes
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
However, I don't know what to put for the second parameter. Each one of the business layer calls takes no parameters, but they each return objects of different types. I tried using delegates but I couldn't figure out how to create one without a defined return type or no parameters. Is it possible to achieve what I want with c#? I know that works in python which is where I'm coming from.
You don't need delegates to do this. Just declare the second parameter as object.
// Takes drop down list and data to assign to 'data source'
private void SourceAndBind(DropDownList d, object data) {
d.DataSource = data;
d.DataBind();
}
// Call methods from bussiness layer and bind results
SourceAndBind(DeptList, bl.getAcademicDepts());
SourceAndBind(TermList, bl.getTerms());
SourceAndBind(InstructorList, bl.getInstructors());
SourceAndBind(EEList, bl.getEE());
You could use delegates too. However, since you're only calling the method once, you can call the bussiness layer method to get the data and then pass the result to SourceAndBind. (Delegates would be useful for example if you wanted to choose one of several ways of loading the data, or if you wanted to delay loading until some later point).
Well, Func<object> would be a very general way of doing that. That's "a function with no parameters that returns an object". Any parameterless function returning a reference type should be convertible to that delegate type. However, your "usage" code wouldn't be quite right as it. It would be:
SourceAndBind(DeptList, bl.getAcademicDepts);
SourceAndBind(TermList, bl.getTerms);
SourceAndBind(InstructorList, bl.getInstructors);
SourceAndBind(EEList, bl.getEE);
Note the lack of brackets, which means these are method groups rather than method calls. (To follow .NET naming conventions I'd suggest renaming your methods to start with capital letters, btw.)
That's appropriate if you only want to call the method conditionally. As Tomas says though, you don't need to use delegates here. If you're happy for SourceAndBind to only get called after you've called the method, you can definitely just perform the method call in the argument and pass the result as object.
private void SourceAndBind(DropDownList d, Func<IEnumerable<object>> businessLayerMethod)
{
d.DataSource = businessLayerMethod();
d.DataBind();
}
IEnumerable<object> where object is your datatype.
Ok, i have a need to be able to keep track of value type objects which are properties on another object, which cannot be done without having those properties implement an IObservable interface or similar. Then i thought of closures and the famous example from Jon Skeet and how that prints out 9 (or 10) a bunch of times and not an ascending order of numbers. So i thought why not do this:
Class MyClass
{
...
Func<MyValueType> variable;
...
public void DoSomethingThatGetsCalledOften()
{
MyValueType blah = variable(); //error checking too not shown for brevity
//use it
}
...
}
... in some other consuming code ...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
//then myClass will get the current value of the variable whenever it needs it
Obviously this would require some understanding of how closures work, but my question is this: is this a good idea or a dirty hack and a misuse of the closure system?
Edit: Since some people seem to be misunderstanding what i'm trying to say, here's a console program which demonstrates it:
using System;
using System.Linq;
namespace Test
{
class Program
{
public static void Main()
{
float myFloat = 5;
Func<float> test = () => myFloat;
Console.WriteLine(test());
myFloat = 10;
Console.WriteLine(test());
Console.Read();
}
}
}
That will print out 5 then 10.
You have stumbled upon the famous koan: Closures are a poor man's object. You are using Action<T> to substitute for a property getter of type T. Such a thing would be (slightly) less of a dirty trick in a more dynamic language, since it could be implemented by injecting a getter that’s decorated with your logging function, but in C# there isn’t an elegant way to monkeypatch someone’s property when they’re not expecting it.
As a mechanism for obtaining the value fro a property, it'll work (but it won't provide any mechanism for noticing updates promptly). However, it depends on how you intend to use it. To do this conveniently you'll need to use a pile of lambdas in the code, or have some DynamicMethod / Expression code do it at runtime. In most cases, something more similar to reflection would be more convenient.
I wouldn't necessarily worry about the "value type" aspect; in most cases this isn't a bottleneck, despite the FUD - and it is generally a lot easier to handle such code with object than it is via generics or similar.
I have some code in my IDE that demonstrates DynamicMethod vs raw reflection (that I intend to blog some day soon), showing how reflection-based code doesn't have to be slow (or just use HyperDescriptor).
The other option is to implement the correct interfaces / add the correct events. Perhaps via PostSharp, perhaps via dynamic types (inheriting and overriding at runtime), perhaps with regular code.
You would need to type your variable member as Func<MyValueType> (or another delegate that returns MyValueType), but you wouldn't be able to assign the value of blah in that manner. Just as with using the closure in the foreach loop above, it's only going to evaluate at a point in time. This isn't a way to keep your variable's value in sync with the other object. There is, in fact, no way to do that without either:
continuously monitoring the value of the other instance's property in some sort of loop, like a Timer
implementing a change notification event on the other instance's class
You would be able to implement a property like that (since a property is evaluated at every call), but then what's the sense in using a custom delegate, other than the fact that you don't have to know anything about the other instance.
Edit
I'll try to make this a little clearer. Using this code that you posted:
Class MyClass
{
...
Action<MyValueType> variable;
...
MyValueType blah = variable();
//use it
...
}
...
MyClass myClass = new MyClass();
myClass.variable = () => myOtherObject.MyOtherProperty;
First, for this to be functional, variable should be Func<MyValueType>, not Action<MyValueType> (Func returns a value, Action does not; since you're trying to assign a value to a variable, you need the expression to return a value).
Second, the main issue with your approach is--assuming I'm reading your code correctly--you're attempting to assign the value of the instance variable blah to the evaluated value of variable() within the class declaration. This won't work for a couple of reasons:
assignments within class declarations cannot access instance members (which variable is)
the assignment of a variable within a class declaration just occurs upon construction of the object. Even if the first condition were present, you would simply get a NullReferenceException upon instantiating your object, since it would be trying to evaluate variable, which would be null at that time
even disregarding the first two, the value of blah would still only represent the evaluated value of variable() at whatever time it was evaluated. It would not "point to" that function and be automatically kept in sync, as it seems like you're trying to do.
If you aren't looking for some sort of automatic synchronization, then there's nothing stopping you from just keeping the Func<MyValueType> delegate around to evaluate; there's nothing particularly good or bad about that approach, and it isn't a closure unless the delegate (in your case a lambda expression) involves the use of a local variable.
The first parameter to a C# extension method is the instance that the extension method was called on. I have adopted an idiom, without seeing it elsewhere, of calling that variable "self". I would not be surprised at all if others are using that as well. Here's an example:
public static void Print(this string self)
{
if(self != null) Console.WriteLine(self);
}
However, I'm starting to see others name that parameter "#this", as follows:
public static void Print(this string #this)
{
if(#this != null) Console.WriteLine(#this);
}
And as a 3rd option, some prefer no idiom at all, saying that "self" and "#this" don't give any information. I think we all agree that sometimes there is a clear, meaningful name for the parameter, specific to its purpose, which is better than "self" or "#this". Some go further and say you can always come up with a more valuable name. So this is another valid point of view.
What other idioms have you seen? What idiom do you prefer, and why?
I name it fairly normally, based on the use. So "source" for the source sequence of a LINQ operator, or "argument"/"parameter" for an extension doing parameter/argument checking, etc.
I don't think it has to be particularly related to "this" or "self" - that doesn't give any extra information about the meaning of the parameter. Surely that's the most important thing.
EDIT: Even in the case where there's not a lot of obvious meaning, I'd prefer some meaning to none. What information is conferred by "self" or "#this"? Merely that it's the first parameter in an extension method - and that information is already obvious by the fact that the parameter is decorated with this. In the example case where theStringToPrint/self option is given, I'd use outputText instead - it conveys everything you need to know about the parameter, IMO.
I name the variable exactly how I would name it if it were a plain old static method. The reason being that it can still be called as a static method and you must consider that use case in your code.
The easiest way to look at this is argument validation. Consider the case where null is passed into your method. You should be doing argument checking and throwing an ArgumentNullException. If it's implemented properly you'll need to put "this" as the argument name like so.
public static void Print(this string #this) {
if ( null == #this ) {
throw new ArgumentNullException("this");
}
...
}
Now someone is coding against your library and suddenly gets an exception dialog which says "this is null". They will be most confused :)
This is a bit of a contrived example, but in general I treat extension methods no different that a plain old static method. I find it makes them easier to reason about.
I have seen obj and val used. I do not like #this. We should try to avoid using keywords. I have never seen self but I like it.
I call it 'target', since the extension method will operate on that parameter.
I believe #this should be avoided as it makes use of the most useless language-specific feature ever seen (#). In fact, anything that can cause confusion or decrease readability such as keywords appearing where they are not keywords should be avoided.
self reminds me of python but could be good for a consistent naming convention as it's clear that it's referring to the instance in use while not requiring some nasty syntactic trickery.
You could do something like this...
public static void Print(this string extended)
{
if(extended != null) Console.WriteLine(extended);
}