Own IEnumerable.First(...) implementation without implicitly captured closure (ReSharper) - c#

I basically want to create my own implementation of LINQ .First(item =>...) and .Single(item => ...), objects only, which throws an exception with a meaningful message for the logfile:
var items = new List<Item>();
// fill items...
var itemIdToFind = 1234; // not supposed to be constant
var itemFound = items.First(
i => i.ID==1234,
() => new NotFoundException("Item " + itemIdToFind + " not found in items"));
Implementation is like this:
internal static class MyExtendedLinq
{
public static T First<T, TEx>(this IEnumerable<T> elements, Func<T, bool> predicate, Func<TEx> notFoundErrorFunc)
where TEx : Exception
{
var firstOnly = elements.Where(predicate).Take(1).ToArray();
// don't confuse found default value with default due to element not found - not FirstOrDefault!.
if (firstOnly.Length == 1)
{
return firstOnly[0];
}
throw notFoundErrorFunc(); // don't care for null func in example
}
}
This keeps giving me the Implicitly Captured Closure warning from ReSharper, both for the Exception lambda and the predicate function.
Especially for the Func predicate, I see no difference to the regular LINQ First(predicate) implementation, which doesn't show this warning.
I don't want the meaningless InvalidOperationExceptions from the regular First(prediate) method, leaving people searching for days, where something expected is missing.

The difference in your case is that you have two different lambdas, each of which are closing over different variables. Enumerable.First only has a single lambda, so it can't do that.
Now, you don't need to care about this warning, because neither delegate is long lived (neither will even outlive either variable), so there is no problem here. Of course, Resharper can't know that, and so has chosen to warn you about it so that you can determine that there isn't actually a problem here.

Related

Delegate chain method results to function body

Trying to build a formatting delegate/function. It's mainly for printing exercise results.
I am trying to access the result of a argument but I think my understanding of delegates is still kind of bad. The method is invokable in the block itself but I would like the result, currently it prints the result definition.
System.Func2[ConsoleApp1.LoanQueries,System.Collections.Generic.IEnumerable1[System.Decimal]]
Below is the code that will create to result to parse, the parsing method and a code snippet that I based my code on.
My questions are:
Is this possible or am I breaking some rules?(trying to use expressions/functional)
Is it possible to declare just a delegate instead of the function(This would probably involve formatting every time instead of the function.)
Create data to format
// Method bodied expression
public IEnumerable<decimal> LoanQueryBodied =>
from amount in LoanAmounts
where amount % 2 == 0
orderby amount ascending
select amount;
// Query expression:
public IEnumerable<decimal> LoanQueryExpression () =>
LoanAmounts
.Where(a => a % 2 == 0)
.OrderBy(r => r);
Method for data and final formatting
public static void FormatLoans<TObject>(
Func<TObject> instance,
Func<TObject, IEnumerable<decimal>> function)
{
// This is the function object but should be IEnumerable<decimal> result passed down.
// Just like TObject is passed , but how?
Console.WriteLine(string.Join(" - ",function));
}
Use method
LoanQueries.FormatLoans<LoanQueries>(() =>
new LoanQueries()
, inst => inst.LoanQueryBodied);
LoanQueries.FormatLoans<LoanQueries>(() =>
new LoanQueries()
, inst => inst.LoanQueryExpression());
Code that I based it loosely on
public static class Disposable
{
public static TResult Using<TDisposable, TResult>(
Func<TDisposable> factory,
Func<TDisposable, TResult> map)
where TDisposable : IDisposable
{
using (var disposable = factory())
{
return map(disposable);
}
}
}
Example invoked
var time= Disposable
.Using(
() => new WebClient(),
client => XDocument.Parse(client.DownloadString("http://time.gov/actualtime.cgi")))
.Root
.Attribute("time")
.Value;
I would like to chain my method like this but if this is not possible or bad practice I would also like to know.
You need to call function and instance using ():
Console.WriteLine(string.Join(" - ",function(instance())));
And apparently you want to return the string, rather than printing it, to allow chaining, so:
public static string FormatLoans<TObject>(
Func<TObject> instance,
Func<TObject, IEnumerable<decimal>> function) =>
string.Join(" - ",function(instance()));
However, I think you are really over-complicating/over-generalising this. Your method is not nearly as general as the Disposable.Using method you showed. Your method could just be declared like this:
public static string FormatLoans(IEnumerable<decimal> loans) =>
string.Join(" - ", loans);
Callers:
LoanQueries.FormatLoans(new LoanQueries().LoanQueryBodied)
LoanQueries.FormatLoans(new LoanQueries().LoanQueryExpression)
Disposable.Using uses delegates because it is trying to recreate the using statement. The second argument must be evaluated inside the using statement, so that any exceptions thrown lead to the disposal of the IDisposable, which is why it has to be wrapped up in a delegate. If not, the second argument would be evaluated before the Using method runs, and that misses the whole point.
However, your method does not have special requirements like that, so you don't need delegates.

How to use the Either type in C#?

Zoran Horvat proposed the usage of the Either type to avoid null checks and to not forget to handle problems during the execution of an operation. Either is common in functional programming.
To illustrate its usage, Zoran shows an example similar to this:
void Main()
{
var result = Operation();
var str = result
.MapLeft(failure => $"An error has ocurred {failure}")
.Reduce(resource => resource.Data);
Console.WriteLine(str);
}
Either<Failed, Resource> Operation()
{
return new Right<Failed, Resource>(new Resource("Success"));
}
class Failed { }
class NotFound : Failed { }
class Resource
{
public string Data { get; }
public Resource(string data)
{
this.Data = data;
}
}
public abstract class Either<TLeft, TRight>
{
public abstract Either<TNewLeft, TRight>
MapLeft<TNewLeft>(Func<TLeft, TNewLeft> mapping);
public abstract Either<TLeft, TNewRight>
MapRight<TNewRight>(Func<TRight, TNewRight> mapping);
public abstract TLeft Reduce(Func<TRight, TLeft> mapping);
}
public class Left<TLeft, TRight> : Either<TLeft, TRight>
{
TLeft Value { get; }
public Left(TLeft value)
{
this.Value = value;
}
public override Either<TNewLeft, TRight> MapLeft<TNewLeft>(
Func<TLeft, TNewLeft> mapping) =>
new Left<TNewLeft, TRight>(mapping(this.Value));
public override Either<TLeft, TNewRight> MapRight<TNewRight>(
Func<TRight, TNewRight> mapping) =>
new Left<TLeft, TNewRight>(this.Value);
public override TLeft Reduce(Func<TRight, TLeft> mapping) =>
this.Value;
}
public class Right<TLeft, TRight> : Either<TLeft, TRight>
{
TRight Value { get; }
public Right(TRight value)
{
this.Value = value;
}
public override Either<TNewLeft, TRight> MapLeft<TNewLeft>(
Func<TLeft, TNewLeft> mapping) =>
new Right<TNewLeft, TRight>(this.Value);
public override Either<TLeft, TNewRight> MapRight<TNewRight>(
Func<TRight, TNewRight> mapping) =>
new Right<TLeft, TNewRight>(mapping(this.Value));
public override TLeft Reduce(Func<TRight, TLeft> mapping) =>
mapping(this.Value);
}
As you see, the Operation returns Either<Failture, Resource> that can later be used to form a single value without forgetting to handle the case in which the operation has failed. Notice that all the failures derive from the Failure class, in case there are several of them.
The problem with this approach is that consuming the value can be difficult.
I'm showcasing the complexity with a simple program:
void Main()
{
var result = Evaluate();
Console.WriteLine(result);
}
int Evaluate()
{
var result = Op1() + Op2();
return result;
}
int Op1()
{
Throw.ExceptionRandomly("Op1 failed");
return 1;
}
int Op2()
{
Throw.ExceptionRandomly("Op2 failed");
return 2;
}
class Throw
{
static Random random = new Random();
public static void ExceptionRandomly(string message)
{
if (random.Next(0, 3) == 0)
{
throw new InvalidOperationException(message);
}
}
}
Please, notice that this sample doesn't user the Either type at all, but the author himself told me that it's possible to do that.
Precisely, I would like to convert the sample above the Evaluation to use Either.
In other words, I want to convert my code to use Either and use it properly
NOTE
It makes sense to have a Failure class that contains the information about the eventual error and a Success class that contains the int value
Extra
It would be very interesting that a Failure could contain a summary of all the problems that may have occurred during the evaluation. This behavior would be awesome to give the caller more information about the failure. Not only the first failing operation, but also the subsequent failures. I think of compilers during a semantic analysis. I wouldn't want the stage to bail out on the first error it detects, but to gather all the problems for better experience.
Either Type Basics
Either type is coming from functional languages where exceptions are (rightfully) considered a side-effect, and therefore not appropriate to pass domain errors. Mind the difference between different kinds of errors: Some of them belong to domain, others don't. E.g. null reference exception or index out of bounds are not related to domain - they rather indicate a defect.
Either is defined as a generic type with two branches - success and failure: Either<TResult, TError>. It can appear in two forms, where it contains an object of TResult, or where it contains an object of TError. It cannot appear in both states at once, or in none of them. Therefore, if one possesses an Either instance, it either contains a successfully produced result, or contains an error object.
Either and Exceptions
Either type is replacing exceptions in those scenarios where exception would represent an event important to the domain. It doesn't replace exceptions in other scenarios, though.
Story about exceptions is a long one, spanning from unwanted side-effects to plain leaky abstractions. By the way, leaky abstractions are the reason why use of the throws keyword has faded over time in the Java language.
Either and Side Effects
It is equally interesting when it comes to side-effects, especially when combined with immutable types. In any language, functional, OOP or mixed (C#, Java, Python, included), programmers behave specifically when they know a certain type is immutable. For one thing, they sometimes tend to cache results - with full right! - which helps them avoid costly calls later, like operations that involve network calls or even database.
Caching can also be subtle, like using an in-memory object a couple of times before the operation ends. Now, if an immutable type has a separate channel for domain error results, then they will defeat the purpose of caching. Will the object we have be useful several times, or should we call the generating function every time we need its result? It is a tough question, where ignorance occasionally leads to defects in code.
Functional Either Type Implementation
That is where Either type comes to help. We can disregard its internal complexity, because it is a library type, and only focus on its API. Minimum Either type allows to:
Map result to a different result, or result of a different type - useful to chain happy path transforms
Handle an error, effectively turning failure into success - useful in the top level, e.g. when representing both success and failure as a HTTP response
Transform one error into another - useful when passing layer boundaries (set of domain errors in one layer needs to be translated into set of domain errors of another layer)
The most obvious benefit from using Either is that functions that return it will explicitly state both channels over which they return a result. And, results will become stable, which means that we can freely cache them if we need so. On the other hand, binding operations on the Either type alone help avoid pollution in the rest of the code. Functions will never receive an Either, for one thing. They will be divided into those operating on a regular object (contained in the Success variant of Either), or those operating on domain error objects (contained in the Failed variant of Either). It is the binding operation on Either that chooses which of the functions will effectively be invoked. Consider the example:
var response = ReadUser(input) // returns Either<User, Error>
.Map(FindProduct) // returns Either<Product, Error>
.Map(ReadTechnicalDetails) // returns Either<ProductDetails, Error>
.Map(View) // returns Either<HttpResponse, Error>
.Handle(ErrorView); // returns HttpResponse in either case
Signatures of all methods used is straight-forward, and none of them will receive the Either type. Those methods that can detect an error, are allowed to return Either. Those that don't, will just return a plain result.
Either<User, Error> ReadUser(input);
Product FindProduct(User);
Either<ProductDetails, Error> ReadTechnicalDetails(Product);
HttpResponse View(Product);
HttpResponse ErrorView(Product);
All these disparate methods can be bound to Either, which will choose whether to effectively call them, or to keep going with what it already contains. Basically, the Map operation would pass if called on Failed, and call the operation on Success.
That is the principle which lets us only code the happy path and handle the error in the moment when it becomes possible. In most cases, it will be impossible to handle error all the way until the top-most layer is reached. Application will normally "handle" error by turning it into an error response. That scenario is precisely where Either type shines, because no other code will ever notice that errors need to be handled.
Either Type in Practice
There are scenarios, like form validation, where multiple errors need to be collected along the route. For that scenario, Either type would contain List, not just an Error. Previously proposed Either.Map function would suffice in this scenario as well, only with a modification. Common Either<Result, Error>.Map(f) doesn't call f in Failed state. But Either<Result, List<Error>>.Map(f), where f returns Either<Result, Error> would still choose to call f, only to see if it returned an error and to append that error to the current list.
After this analysis, it is obvious that Either type is representing a programming principle, a pattern if you like, not a solution. If any application has some specific needs, and Either fits those needs, then implementation boils down to choosing appropriate bindings which would then be applied by the Either object to target objects. Programming with Either becomes declarative. It is the duty of the caller to declare which functions apply to positive and negative scenario, and the Either object will decide whether and which function to call at run time.
Simple Example
Consider a problem of calculating an arithmetic expression. Nodes are evaluated in-depth by a calculation function, which returns Either<Value, ArithmeticError>. Errors are like overflow, underflow, division by zero, etc. - typical domain errors. Implementing the calculator is then straight-forward: Define nodes, which can either be plain values or operations, and then implement some Evaluate function for each of them.
// Plain value node
class Value : Node
{
private int content;
...
Either<int, Error> Evaluate() => this.content;
}
// Division node
class Division : Node
{
private Node left;
private Node right;
...
public Either<Value, ArithmeticError> Evaluate() =>
this.left.Map(value => this.Evaluate(value));
private Either<Value, ArithmeticError> Evaluate(int leftValue) =>
this.right.Map(rightValue => rightValue == 0
? Either.Fail(new DivideByZero())
: Either.Success(new Value(leftValue / rightValue));
}
...
// Consuming code
Node expression = ...;
string report = expression.Evaluate()
.Map(result => $"Result = {result}")
.Handle(error => $"ERROR: {error}");
Console.WriteLine(report);
This example demonstrates how evaluation can cause an arithmetic error to pop up at any point, and all nodes in the system would simply ignore it. Nodes will only evaluate their happy path, or generate an error themselves. Error will be considered for the first time only at the UI, when something needs to be displayed to the user.
Complex Example
In a more complicated arithmetic evaluator, one might want to see all errors, not just one. That problem requires customization on at least two accounts: (1) Either must contain a list of errors, and (2) New API must be added to combine two Either instances.
public Either<int, ArithErrorList> Combine(
Either<int, ArithErrorList> a,
Either<int, ArithErrorList> b,
Func<int, int, Either<int, ArithErrorList>> map) =>
a.Map(aValue => Combine(aValue, b, map);
private Either<int, ArithErrorList> Combine(
int aValue,
Either<int, ArithErrorList> b,
Func<int, int, Either<int, ArithErrorList>> map) =>
b.Map(bValue => map(aValue, bValue)); // retains b error list otherwise
private Either<int, ArithErrorList> Combine(
ArithErrorList aError,
Either<int, ArithErrorList> b,
Func<int, int, Either<int, ArithErrorList>> map) =>
b.MapError(bError => aError.Concat(bError))
.Map(_ => bError); // Either concatenate both errors, or just keep b error
...
// Operation implementation
class Divide : Node
{
private Node left;
private Node right;
...
public Either<int, AirthErrorList> Evaluate() =>
helper.Combine(left.Evaluate(), right.Evaluate(), this.Evaluate);
private Either<int, ArithErrorList> Evaluate(int a, int b) =>
b == 0 ? (ArithErrorList)new DivideByZero() : a / b;
}
In this implementation, the public Combine method is the entry point which can concatenate errors from two Either instances (if both are Failed), retain one list of errors (if only one is Failed), or call the mapping function (if both are Success). Note that even the last scenario, with both Either objects being Success, can eventually produce a Failed result!
Note to Implementers
It is important to note that Combine methods are library code. It is a general rule that cryptic, complex transforms must be hidden from the consuming code. It is only the plain and simple API that the consumer will ever see.
In that respect, the Combine method could be an extension method attached, for example, to the Either<TResult, List<TError>> or Either<TReuslt, ImmutableList<TError>> type, so that it becomes available (unobtrusively!) in those cases where errors can be combined. In all other cases, when error type is not a list, the Combine method would not be available.
For those that are still wondering, there are the Maybe and Result (AKA Either) types in this handy library by Vladimir Khorikov.
https://github.com/vkhorikov/CSharpFunctionalExtensions.
I'm posting this because it's ready to use, powerful and well designed.

How to pass a predicate as parameter c#

How can I pass a predicate into a method but also have it work if no predicate is passed? I thought maybe something like this, but it doesn't seem to be correct.
private bool NoFilter() { return true; }
private List<thing> GetItems(Predicate<thing> filter = new Predicate<thing>(NoFilter))
{
return rawList.Where(filter).ToList();
}
private List<thing> GetItems(Func<thing, bool> filter = null)
{
return rawList.Where(filter ?? (s => true)).ToList();
}
In this expression s => true is the fallback filter which is evaluated if the argument filter is null. It just takes each entry of the list (as s) and returns true.
There are two parts to this.
First, you need to adjust the NoFilter() function to be compatible with Predicate<T>. Notice the latter is generic, but the former is not. Make NoFilter() look like this:
private bool NoFilter<T>(T item) { return true; }
I know you never use the generic type argument, but it's necessary to make this compatible with your predicate signature.
For fun, you could also define NoFilter this way:
private Predicate<T> NoFilter = x => true;
Now the second part: we can look at using the new generic method as the default argument for GetItems(). The trick here is you can only use constants. While NoFilter() will never change, from the compiler's view that's not quite the same things a a formal constant. In fact, there is only one possible constant you can use for this: null. That means your method signature must look like this:
private List<thing> GetItems(Predicate<thing> filter = null)
Then you can check for null at the beginning of your function and replace it with NoFilter:
private List<thing> GetItems(Predicate<thing> filter = null)
{
if (filter == null) filter = NoFilter;
return rawList.Where(filter).ToList();
}
And if you also do want to explicitly pass this to the method when calling it, that would look like this:
var result = GetItems(NoFilter);
That should fully answer the original question, but I don't want to stop here. Let's look deeper.
Since you need the if condition anyway now, at this point I would tend to remove the NoFilter<T>() method entirely, and just do this:
private IEnumerable<thing> GetItems(Predicate<thing> filter = null)
{
if (filter == null) return rawList;
return rawList.Where(filter);
}
Note that I also changed the return type and removed the ToList() call at the end. If you find yourself calling ToList() at the end of a function just to match a List<T> return type, it's almost always much better to change the method signature to return IEnumerable<T> instead. If you really need a list (and usually, you don't), you can always call ToList() after calling the function.
This change makes your method more useful, by giving you a more abstract type that will be more compatible with other interfaces, and it potentially sets you up for a significant performance bump, both in terms of lowered memory use and in terms of lazy evaluation.
One final addition here is, if you do pare down to just IEnumerable, we can see now this method does not really provide much value at all beyond the base rawItems field. You might look at converting to a property, like this:
public IEnumerable<T> Items {get {return rawList;}}
This still allows the consumer of your type use a predicate (or not) if they want via the existing .Where() method, while also continuing to hide the underlying raw data (you can't directly just call .Add() etc on this).

Type Cast error from lambda to delegate

I have been following this Example to implement LazyLoading, to initialize lazyObject with some value i am making a call to function with the help of Lambda Expression. But, i am getting Conversion error and its saying its not delegate. Below is the code:
private Lazy<t_user_audit> lazyList = null;
lazyList = new Lazy<t_user_audit>(() => new t_user_audit { client.GetAudit(10) });
I have searched the error on google, but its does not seems to be helpful and further i have seen this error first time in my life, so might be i am in need of coding help with proper syntax. So can anybody help me now.
public t_user_audit GetAudit(int id)
{
return _work.GetGenericRepositoryFor<t_user_audit>().SingleOrDefault(p => p.CustomerId == id);
}
Now, as you can see i am working in layered architecture, so i won't be able for me to post the whole code and one more thing i am using Entity Framework.
After, using the above line, i get two errors:
Error 17 Cannot convert lambda expression to type 'bool' because it is not a delegate type
And the second is:
Error 18 Cannot initialize type 'BBTI.Entities.t_user_audit' with a collection initializer because it does not implement 'System.Collections.IEnumerable'
New answer with edited question
The problem is that your lambda expression isn't valid - you're trying to use collection initializer syntax, but your type isn't a collection. So instead of this:
() => new t_user_audit { client.GetAudit(10) }
You want:
() => new List<t_user_audit> { client.GetAudit(10) }
Original answer
From the comments:
"it will return an object with single record"
If you mean that GetAudit is declared to return a t_User, like this:
public t_User GetAudit(int something)
then that's the problem. To create a Lazy<List<Foo>> you need a delegate which will return a List<Foo>, not a single Foo. So this should work:
lazyList = new Lazy<List<t_User>>(() => new List<t_User> { client.GetAudit(10) });
Or you could make it a Lazy<t_User> instead, if you're only ever going to fetch a single use.
Another possibility (it's hard to tell as you haven't given enough information in the question) is that GetAudit returns something like an IEnumerable<t_User> instead of a List<t_User>. In that case, you would just need to create a list from the return value:
lazyList = new Lazy<List<t_User>>(() => client.GetAudit(10).ToList());
(I'd also strongly encourage you to start following .NET naming conventions, and ditch the t_ prefix.)

Can a C# lambda expression ever return void?

I have the following method, and I want to know if there is anything that can go in place default(void) below because there is a compiler error that says that void is not valid here:
private void applyDefaultsIfNecessary(ApplicationConfiguration configuration)
{
var defaults = new Dictionary<Predicate<ApplicationConfiguration>, Action<ApplicationConfiguration>>()
{
// { rule, action } - if rule is true, execute action
{ (c) => c.ConnectionString == null , (c) => c.ConnectionString = "foo" },
{ (c) => c.OutputExcelFilePath == null, (c) => c.ConnectionString = "bar" },
{ (c) => c.OutputDirectory == null, (c) => c.OutputDirectory = "baz" }
};
//Nothing to select, but we want to loop throough the dict and invoke action, if rule is true.
//It is a pity there is no extension method called DoForEach on collections.
defaults.Select((item) => item.Key.Invoke(configuration) ? item.Value.Invoke(configuration) : default(void) );
}
I realize that I can use the if-else statement instead of the ternary operator (or that I could call a dummy method to return void). Also, the Select extension method does not like lambdas that return void. It seems to say that the type cannot be inferred, but of course if I specify the type like this, either:
defaults.Select<ApplicationConfiguration, void>((item) => { if (item.Key.Invoke(configuration)) item.Value.Invoke(configuration); } );
I was curious from a language design standpoint, why we don't have expressions that can return void or the data type for variables that is void.
I refer you to section 7.1 of the specification, which states:
[An expression may be classified as]
"nothing". This occurs when the
expression is an invocation of a
method with a return type of void.
An expression classified as nothing is only valid in the context of a
statement expression.
[Emphasis added].
That is to say that the only time you may use an expression which is a void-returning method invocation is when the expression makes up an entire statement. Like this:
M();
This is, in effect, a violation of functional programming rules. This has the same flaw Eric Lippert described about List.ForEach: You're philosphically trying to cause side effects on your collection.
Enumerable.Select is intended to return a new collection - filtering the input. It is not intended to execute code.
That being said, you can work around this by doing:
defaults.Where(item => item.Key.Invoke(configuration)).ToList().ForEach( item => item.Value.Invoke(configuration));
It's just not as clear as doing:
var matches = defaults.Where(item => item.Key.Invoke(configuration));
foreach(var match in matches)
match.Value.Invoke(configuration);
Firstly, you should really avoid putting side-effects in standard linq query operators, and secondly this won't actually work since you aren't enumerating the Select query anywhere. If you want to use linq you could do this:
foreach(var item in defaults.Where(i => i.Key.Invoke(configuration)))
{
item.Value.Invoke(configuration);
}
Regarding your question, I'm pretty sure there are no possible values of void and you can't return it explicity. In functional languages such as F#, void is replaced with 'unit' i.e. a type with only one possible value - if you wanted you could create your own unit type and return that. In this case you could do something like this:
defaults.Select(item => {
if(item.Key.Invoke(configuration))
{
item.Value.Invoke(configuration);
}
return Unit.Value;
}).ToList();
But I really can't recommend doing this.
From a language standpoint, void means "does not exist", which begs the question: what value would there be in declaring a variable that does not exist?
The problem here is not a language limitation but the fact that you're using a construct (the ternary operator) that demands two rvalues -- where you only have one.
If I may be blunt, I'd say you're avoiding if/else in favor of pointless brevity. Any tricks you come up with to replace default(void) will only serve to confuse other developers, or you, in the future, long after you've stopped bothering with this sort of thing.
default doesn't work with void; but it works with a type. The Action class produces no result, but the Func<> object always has to return a result. Whatever item.Value.Invoke() returns just return the default of that, as in:
default(object)
or if it's a specific type:
default(SomeType)
Like that.

Categories