Inline variable using custom LINQ Extension Method - c#

I have created a little LINQ extension method that allows me to use a value for very small code without going through the hassle of declaring a local variable.
public static TReturn Do<TInput, TReturn>(this TInput input, Func<TInput, TReturn> func)
=> func(input);
I use it to inline slightly more expensive expressions that I only use in one place, such as:
var ImportantValue = MyDatabase.First(e => e.Id == 28131).Do(e =>
{
Console.WriteLine(e.Name);
MyOtherDatabase.Add(new Foo(e.FooParameter));
return e.ImportantValue;
});
This is useful as duplicating the MyDatabase.First(e => e.Id == 28131) statement would be a performance hit, and creating a local for it would just clutter up the scope needlessly, as it is only ever used in that one spot.
Furthermore this allows for using expression bodies in places where you usually would have to use a block statement, only to have it be two lines long.
However, I am not sure that the name Do is very descriptive or useful, and I can't think of any better names for this. As I am using this in more and more code, I would like to give it a proper, descriptive name.

A better name than Do is possibly Apply. But this extension method will be callable for all types of the .NET Framework, so it will clutter the intellisense list of everything. Being on the top of the list would be extra irritating, so I would be inclined to name it with something starting from X, Y or Z, to move it to the bottom. Personally I would prefer not to have an extension method like this at all.

Related

Why is Action/Func better than a regular Method in .Net?

I much prefer using an Action or a Func if I need a quick reusable piece of code, however others on my team don't like them or understand them.
At the moment my only real argument is about preference and more up to date code practices, but those are just bad arguments.
Why is it better to do this:
Action<FormView,String> hideControl = (form,name) => {
var button = form.GetControl<Button>(name);
if (button != null)
button.Visible = false;
}
than:
public static void HideControl<T>(this FormView form, string name) where T : Control
{
var button = form.GetControl<Button>(name);
if (button != null)
button.Visible = false;
}
?
Can anyone give me solid concrete arguments/examples?
There are two sides to your question: style and performance.
For code style, using delegates makes things a little messy. There is no function name associated with the body of code (anonymous method), argument types are inferred, and when overused this can lead to large function blocks containing lots of smaller independent chunks of code in delegates. It's not pretty to look at, it can be hard to figure out what the code is actually doing, and it's hard to find what you're looking for.
For performance, delegates introduce an indirection that is not as fast to execute as a plain old method. The difference is small, but when used to excess it could become noticeable.
Any tool has appropriate and excessive uses. It's appropriate to use Action or Func for a callback parameter when you want to pass a callback routine into a function. Using Action or Func as a replacement for declaring functions in general is a misuse, IMO.
The short answer is that, in general, it is not better. I agree with your team mates.
I don't think your question is the right one. Rather than asking why is it better (believe me it is not in most cases), you might ask WHEN is it better.
Now, there are of course times where they are extremely useful, like in LINQ when methods take in a Func, writing a quick lambda is great.
This is far more readable and maintainable:
var myQuery = Customers.Where(x => x.ID == 3).First();
than the alternative:
public bool FilterByID3(Customer cust)
{
return cust.ID == 3;
}
var myQuery = Customers.Where(FilterByID3).First();
In most other cases, it is much more readable/maintainable to use functions.
Why is it better to do this
It's not better. In that case I don't see any advantages in doing this rather than writing a real method. And if you can't either, I don't understand why you're so sure it's better.
Avoid writing long anonymous methods (and by long, I mean more than one or two lines), it just makes the code less readable.
There are however some cases where it can be useful to use an anonymous method: closures. If you need to capture a local variable, then anonymous methods are the way to go. But even then, don't write a long piece of code in it: just call a real method to which you pass the captured variable as a parameter.
In general I agree with the other answerers: Blindly replacing function definitions with Action/Func is not a good thing. Action and Func are not the future of .NET. They are a tool which is very useful but like any tool can be misused.
So if you tend to write code like this
class SomeClass {
Action<...> a1 = (..) => {};
Func<...> f1 = (..) => {};
Action<...> a2 = (..) => {};
...
}
That is certainly not a good thing.
If you do this a lot:
void SomeMethod()
{
Action<..> a = (..) => {};
...
a();
}
then this is actually a good way of encapsulating a little helper method without polluting the class.
To argue your specific case:
If hideControl is only used in a very specific case the private helper method would be preferred. If it is required for a lot of FormViews then the extension method makes more sense. Extension methods are also a tool which can be misused as it can lead to pollution of the public interface for a class. Although you can limit it through the use of namespaces.
I usually go by this guideline:
If you require a helper method which is useful in a lot of places and situations and can be made fairly generic I create an extension method.
If it is a helper method which is required for a specific class but in a several places (methods) in that class then I create a private method.
If it is a helper which I only need in one specific place then I make it a Action/Func inside that method.
Pros
Closures
This does not help your case though.
Super-private methods -- only the defining method can call it.
This is easily countered with the Single Responsibility Principle though. You're likely combining what should be a different class in an entire method.
Callbacks
These can also easily be methods.
Cons
Readability is lessened, in my opinion, because of the excess indentation (I'm not a fan).
Debugging becomes a little harder because your call stack is less intuitive especially when you have multiple Func/Action's defined.
You'll have to over come the cons in your environment.
I'm curious about your "more up-to-date coding practice" argument. Just because you can do this as much as possible doesn't mean you should.

Func<T, TResult> delegate real world uses

I've recently been playing around with the delegate Func<T, TResult> and creating methods that return different instances Func<T, TResult> containing lambda but what I have struggled to come up with is any good real world ideas of why one might want to return (or even create such an instance).
There is an example on MSDN where they do the following...
Func<string, string> convertMethod = UppercaseString;
private static string UppercaseString(string inputString)
{
return inputString.ToUpper();
}
And although it looks pretty and is an interesting concept I fail to see what advantages such code provides.
So could someone here please provide any real world examples where they have had to use Func<T, TResult> and in general why one might want to use this delegate?
If what you're asking, really, is why we have delegates in general:
If you've ever consumed an event, you've used a delegate
If you've ever used LINQ, you've used a delegate (technically, with an IQueryable provider you've used an expression, but for LINQ-to-Objects you've used a delegate)
Delegates provide a way of injecting your own behavior into another object. The most common usage is with events. An object exposes an event and you provide a function (anonymous or not) that gets called when that event fires.
If you're asking why we have the Func<T, TResult> (and similar) delegate, then there are two main reasons:
People were having to declare their own simple delegate types when they needed a particular delegate in their code. While the Action<> and Func<> delegates can't cover all cases, they are simple to provide and cover many of the cases where custom delegates were needed.
More importantly, the Func<T, TResult> delegate is used extensively in LINQ-to-Objects to define predicates. More specifically, Func<T, bool>. This allows you to define a predicate that takes a strongly-typed member of an IEnumerable<T> and returns a boolean by using either a lambda or ordinary function, then pass that predicate to LINQ-to-Objects.
You would use it a lot in LINQ. So, for example, to double all the numbers in a list:
myList.Select(x => x * 2);
That's a Func<TIn, TOut>. It's quite useful when creating concise code. A real-world example is in one of the many tower-defence games I made, I calculated the closest enemy to the tower using one line:
enemies.Select(x => tower.Location.DistanceTo(x.Location)).OrderBy(x => x).FirstOrDefault();
I think a great example is lazy initialization.
var value = new Lazy<int>(() => ExpensiveOperation()); // Takes Func<T>
The canonical example of a need for a function pointer is for a comparison function to pass to a sort routine. In order to have different sort keys, you create a lambda for the comparison function, and pass that to the sort function.
Or for a simple real-world example:
IEnumerable<Person> FindByLastName(string lastName)
{
return Customers.Where(cust => cust.LastName == lastName);
}
In this example, cust => cust.LastName == lastName is not just a lambda, but it creates a closure by capturing the lastName parameter. In othe words, it creates a function, which will be different every time FindByLastName is called.
The Func<T> delegate (and other overloads) give you new ways for writing abstractions in C#. To demonstrate some of the options, here are a couple of C# langauge constructs that could be written using delegates instead:
Thread.Lock(obj, () => {
// Safely access 'obj' here
});
Enumerable.ForEach(collection, element => {
// Process 'element'
});
Exceptions.Try(() => {
// Try block
}).With((IOException e) => {
// Handle IO exceptions
});
These are quite primitive, so it is good to have a language construct for them. However, it demonstrates that Func and lambda expressions add quite a lot of expressive power. It makes it possible to write new constructs such as parallel loop (using .NET 4.0):
Parallel.ForEach(collection, element => {
// Process 'element'
});
First of all, Func<T> is not a class, it's a delegate.
Basically, you can use it whenever you need a method argument or a property of delegate type if you don't want to declare your own delegate for that.
One great use of Funct<T>, besides the fact that it is embedded in many frameworks such as LINQ, Mocking Tools, and Dependency Injection containers is to use it to create a delegate based factory.
Recently, I wanted the external program calling my method to be able to modify the way it behaves.
My method in itself simply converts a file from XLS to XML. But it was necessary to allow the calling code to specify if needed an arbitrary number of transformations which should apply to each xls cell before being writing as a xml tag. For example : convert the "," decimal separator to ".", suppress the thousand separator, and so on (the transformations were all string replacements).
Then the caller code just had to add an arbitrary number of entries in a dictionary where the key is the pattern and the value is the replacement string for this pattern. My method loops over the dictionary and creates a new Func<string,string> for each entry. Then for each cell the Func<string,string> are applied in sequence.

Extension method that extends T - bad practice?

I've read that it is usually bad practice to extend System.Object, which I do agree with.
I am curious, however, if the following would be considered a useful extension method, or is it still bad practice?
It is similar to extending System.Object but not exactly,
public static R InvokeFunc<T, R>(this T input, Func<T, R> func)
{
return func.Invoke(input);
}
This essentially allows any object to invoke any function that takes that object as a parameter and returns R, whether that function belongs to the object or not. I think this could facilitate some interesting 'inversion of control', but not sure about it overall.
Thoughts?
Well there are really two points here:
1) Whether it is a good idea to create an extension method with this T so it will be applied to all types?
2) Whether the particular extension method described is useful?
For the 1st question the answer is sometimes but depends on the context. You can have an extension method apply to all classes just like linq does ensuring that you pick an appropriate namespace. I would think creating this type of extension method within the System namespace a bad idea but if it were more targeted then perhaps it would be useful.
For the 2nd since the invoke is immediate then the choice of syntax is as follows
int res = other.InvokeFunc<Other, int>(Callback);
var res2 = (new Func<Other, int>(Callback))(other);
var res3 = Callback(other);
Looking at that then a simple call to the method passing the instance in is more natural and typical, however if your extension method becomes more elaborate then I go back to my first point on that it depends on the context (which could help with encapsulation).
All this does is that it gives you the ability to refer to a method as a parameter which is in fact what delegates already allow you in C#.
I don't see it being more useful (in case of IoC) than a delegate of type Func<T,R> in your case. It's just another way of invoking it.
UPDATE
As mentioned in the comments, I think this method only helps you in creating delegates more efficiently. But either way, you do not use the created delegate any further since you invoke it immediately. So an extension method like this would make more sense to me:
public static Func<R> InvokeFunc<T, R>(this T input, Func<T, R> func)
{
return () => func(input);
}

C# Linq question

Does LINQ have a sequence operator, which allows to perform some action on every element without projecting it to a new sequence?
This might see a bit awkward, but just for me to know :)
Example:
IEnumerable<IDisposable> x;
x.PERFORM_ACTION_ON_EVERY_ELEMENT(m => m.Dispose());
Obviously, this could be done using something like:
foreach (var element in x) x.Dispose();
But if something actually exists, that would be nice.
No, it doesn't exist. Specifically for the reason you mention: It seems awkward having a single operator that behaves completely different than all the others.
Eric Lippert, one of the C# Compiler developers has an article about this.
But we can go a bit deeper here. I am philosophically opposed to providing such a method, for two reasons.
The first reason is that doing so violates the functional programming principles that all the other sequence operators are based upon. Clearly the sole purpose of a call to this method is to cause side effects.
The purpose of an expression is to compute a value, not to cause a side effect. The purpose of a statement is to cause a side effect. The call site of this thing would look an awful lot like an expression (though, admittedly, since the method is void-returning, the expression could only be used in a “statement expression” context.)
It does not sit well with me to make the one and only sequence operator that is only useful for its side effects.
You can use this method:
public static class Extension
{
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (var t in source)
{
action(t);
}
return source;
}
}
It returns the source so you can pass it along to another extension method as needed. Or if you want to be void, you can change the method a little bit.
The morelinq project has a ForEach operator. LINQ itself doesn't, as LINQ is all about functional programming, and ForEach has side effects.
Here is a similar dicussion on this Run a method on all objects within a collection

C# method group strangeness

I discovered something very strange that I'm hoping to better understand.
var all = new List<int[]>{
new int[]{1,2,3},
new int[]{4,5,6},
new int[]{7,8,9}
};
all.ForEach(n => n.ForEach(i => Console.WriteLine(i)));
which can be rewritten as:
...
all.ForEach(n => n.ForEach(Console.WriteLine));
How is it possible to leave out the lambda expression parameter (i=>) and still have the current item passed to console.WriteLine?
Thanks for any insight.
-Keith
List<T>.ForEach is looking for an Action<T>. When you write
n.ForEach(Console.WriteLine);
what you have here is one of the members of the method group Console.WriteLine playing the role of an Action<T>. The compiler will look for the best overload of Console.WriteLine that eats instances of int. In fact, it will use the overload Console.WriteLine(int). It will then use this overload to play the role of an Action<int>.
For details on how this is done, see §6.6 of the specification (Method group conversions).
However, when you write
n.ForEach(i => Console.WriteLine(i));
we actually have a very different Action<int> In the first case, the Action<int> was Console.WriteLine(int). Here, the Action<int> is equivalent to you having written
public static void DoSomething(int i) {
Console.WriteLine(i);
}
and then
n.ForEach(DoSomething);
(Of course, the compiler has to go through the same method group process as described above to figure out what is meant by DoSomething).
The point is that in the first case the Action<int> is Console.WriteLine(int). However, in the second case the Action<int> is a middle man (the lambda expression) that itself will call Console.WriteLine(int).
This is less confusing if you consider what is really happening.
You are passing a method to a delegate argument. Most of the time, we think of delegates in the context of events, but they can be parameters to methods as well. It doesn't seem odd when a method is added to an event without arguments, it just is unusual looking when executed in this context.
Before lambdas, you had to do this all the time, and it was such a pain that one would never consider using a library that looked like LINQ. With Lambdas, this is easier to do, but you can always do the old way as well.

Categories

Resources