How to pass method on LINQ-generated object as delegate? - c#

I have the following method (where SetTypes is an enum):
public IEnumerable<Chart> RetrieveCharts(IEnumerable<string> filters, SetTypes set)
{
switch (set)
{
case SetTypes.Set: return GetChartsSet(filters);
case SetTypes.Subset: return GetChartsSubset(filters);
// Other cases here...
default:
throw new NotImplementedException();
}
}
I am duplicating code across my method calls ... the only thing that's changing is the method call on the HashSet instance:
private IEnumerable<Chart> GetChartsSet(IEnumerable<string> filters)
{
using (var db = new ChartContext())
{
return db.Charts.Where(c => new HashSet<string>(c.ProductFilters.Select(f => f.Filter)).SetEquals(filters)).Select(c => c);
}
}
private IEnumerable<Chart> GetChartsSubset(IEnumerable<string> filters)
{
using (var db = new ChartContext())
{
return db.Charts.Where(c => new HashSet<string>(c.ProductFilters.Select(f => f.Filter)).IsProperSubsetOf(filters)).Select(c => c);
}
}
// More duplicated methods follow...
Instead of having multiple methods simply to call a different method on HashSet, I'd prefer a consolidated method which takes the HashSet method as an argument - but I'm not sure how to proceed. How do I do this?
Bonus points if you also tell me how to get rid of that switch statement. :)

You could make a common implementation that takes an additional Predicate<HashSet<string>> on the set:
private IEnumerable<Chart> GetWithPredicate(Predicate<HashSet<string>> pred) {
using (var db = new ChartContext()) {
return db.Charts
.Where(c => pred(new HashSet<string>(c.ProductFilters.Select(f => f.Filter))))
.Select(c => c);
}
}
and then reuse it in different methods:
private IEnumerable<Chart> GetChartsSet(IEnumerable<string> filters) {
return GetWithPredicate(s => s.SetEquals(filters));
}
private IEnumerable<Chart> GetChartsSubset(IEnumerable<string> filters) {
return GetWithPredicate(s => s.IsProperSubsetOf(filters));
}

Related

I want to iterate through my priority queue in C#

I am implementing a generic priority queue in C# i used SortedDictionary for the priority keys and Queue for the values.
Now i want to iterate through it with a foreach loop with a condition to skip over queue items with priority 0.
This is my priority queue class
public class PQ<Tpriority, Titem>
{
readonly SortedDictionary<Tpriority, Queue<Titem>> value;
public PQ(IComparer<Tpriority> priorityComparer)
{
value = new SortedDictionary<Tpriority, Queue<Titem>>(priorityComparer);
}
public PQ() : this(Comparer<Tpriority>.Default) { }
public bool Check{ get { return value.Any(); }}
public int Count
{
get { return value.Sum(q => q.Value.Count); }
}
public void Add(Tpriority priority, Titem item)
{
if (!value.ContainsKey(priority))
{
AddQueueOfPriority(priority);
}
value[priority].Enqueue(item);
}
private void AddQueueOfPriority(Tpriority priority)
{
value.Add(priority, new Queue<Titem>());
}
public Titem Next()
{
if (value.Any())
return Next_FHP();
else
throw new InvalidOperationException("The queue is empty");
}
private Titem Next_FHP()
{
KeyValuePair<Tpriority, Queue<Titem>> first = value.First();
Titem nextItem = first.Value.Dequeue();
if (!first.Value.Any())
{
value.Remove(first.Key);
}
return nextItem;
}
public SortedDictionary<Tpriority, Queue<Titem>>.Enumerator GetEnumerator()
{
return value.GetEnumerator();
}
}
public interface IEnumerator<Tpriority, Titem>{}
And this is my main program
I was able to get all my needed actions to work fine just this
static
void Main(string[] args)
{
var first = new PQ<int, string>();
first.Add(1, "random1");
first.Add(0, "random2");
first.Add(2, "random3");
while (first.Check)
{
Console.WriteLine(first.Next());
}
Console.WriteLine(first.Check);
/*it gives the error "Can not convert
type 'System.Collections.Generic.KeyValuePair<int,System.Collections.Generic.Queue<string>>'
to exam.PQ<int, string>"*/
foreach (PQ<int, string> h in first)
{
}
}
Thank you.
One way to do it would be to add your own method on your PQ class, that returns a collection of Queue items that pass your (any) validation check.
So something like this on your PQ class
public IEnumerable<Queue<Titem>> GetItems(Tpriority priority)
{
var validKeys = value.Keys.Where(x => !x.Equals(priority) );
return value.Where(x => validKeys.Contains(x.Key)).Select(x => x.Value);
}
Then you can iterate over it like this
foreach (var h in first.GetItems(0))
{
}
You might want a better name for the method though, which clearly states what it's going to do.
Update...
To just print out the values, you could do something like this.
public IEnumerable<Titem> GetItems(Tpriority priority)
{
var validKeys = value.Keys.Where(x => !x.Equals(priority) );
return value
.Where(x => validKeys.Contains(x.Key))
.SelectMany(x => x.Value);
}
And here it is broken up into bits with a few comments
public IEnumerable<Titem> GetItems(Tpriority priority)
{
// Find all the keys in the dictionary which do not match the supplied value
var validKeys = value.Keys.Where(x => !x.Equals(priority) );
// Find all the values in the dictionary where the key is in the valid keys list
var validItems = value
.Where(x => validKeys.Contains(x.Key));
// Because an individual queue item is actually a collection of items,
// SelectMany flattens them all into one collection
var result = validItems.SelectMany(x => x.Value);
return result;
}

Convert IEnumerable<Task<T>> to IObservable<T> with exceptions handling

I want to convert IEnumerable<Task<T>> to IObservable<T>. I found solution to this here:
IObservable<T> ToObservable<T>(IEnumerable<Task<T>> source)
{
return source.Select(t => t.ToObservable()).Merge();
}
It is perfectly ok for usual cases, but I need to handle exceptions, that could raise in that Tasks... So IObservable<T> should not be dead after first exception.
What I read, recommendation for this use case is to use some wrapper, that will carry actual value or error. So my attempt was
IObservable<Either<T, Exception>> ToObservable<T>(IEnumerable<Task<T>> source)
{
var subject = new Subject<Either<T, Exception>>();
foreach (var observable in GetIntsIEnumerable().Select(t => t.ToObservable()))
{
observable.Subscribe(i => subject.OnNext(i), e => subject.OnNext(e));
}
return subject;
}
With Either<T, Exception> borrowed from this article.
But this is not ok either, because OnCompleted() is not called. How should I solve it? I'm pretty new with Rx concept.
Here is full code for testing...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
namespace Test
{
class Program
{
static Task Main()
{
SemaphoreSlim signal = new SemaphoreSlim(0, 1);
//GetInts1().Subscribe(
// i => Console.WriteLine($"OK: {i}"),
// e => Console.WriteLine($"ERROR: {e.Message}"),
// () => signal.Release());
GetInts2().Subscribe(r => Console.WriteLine(r.Match(
i => $"OK: {i}",
e => $"ERROR: {e.Message}")),
() => signal.Release());
return signal.WaitAsync();
}
static IObservable<int> GetInts1()
{
return GetIntsIEnumerable().Select(t => t.ToObservable()).Merge();
}
static IObservable<Either<int, Exception>> GetInts2()
{
var subject = new Subject<Either<int, Exception>>();
foreach (var observable in GetIntsIEnumerable().Select(t => t.ToObservable()))
{
observable.Subscribe(i => subject.OnNext(i), e => subject.OnNext(e));
}
return subject;
}
static IEnumerable<Task<int>> GetIntsIEnumerable()
{
Random rnd = new Random();
foreach (int i in Enumerable.Range(1, 10))
{
yield return Task.Run(async () =>
{
await Task.Delay(rnd.Next(0, 5000));
if (i == 6)
throw new ArgumentException();
return i;
});
}
}
}
/// <summary>
/// Functional data data to represent a discriminated
/// union of two possible types.
/// </summary>
/// <typeparam name="TL">Type of "Left" item.</typeparam>
/// <typeparam name="TR">Type of "Right" item.</typeparam>
public class Either<TL, TR>
{
private readonly TL left;
private readonly TR right;
private readonly bool isLeft;
public Either(TL left)
{
this.left = left;
this.isLeft = true;
}
public Either(TR right)
{
this.right = right;
this.isLeft = false;
}
public T Match<T>(Func<TL, T> leftFunc, Func<TR, T> rightFunc)
{
if (leftFunc == null)
{
throw new ArgumentNullException(nameof(leftFunc));
}
if (rightFunc == null)
{
throw new ArgumentNullException(nameof(rightFunc));
}
return this.isLeft ? leftFunc(this.left) : rightFunc(this.right);
}
/// <summary>
/// If right value is assigned, execute an action on it.
/// </summary>
/// <param name="rightAction">Action to execute.</param>
public void DoRight(Action<TR> rightAction)
{
if (rightAction == null)
{
throw new ArgumentNullException(nameof(rightAction));
}
if (!this.isLeft)
{
rightAction(this.right);
}
}
public TL LeftOrDefault() => this.Match(l => l, r => default);
public TR RightOrDefault() => this.Match(l => default, r => r);
public static implicit operator Either<TL, TR>(TL left) => new Either<TL, TR>(left);
public static implicit operator Either<TL, TR>(TR right) => new Either<TL, TR>(right);
}
}
There's a built-in mechanism for handling errors like this. Simply use the .Materialize() operator which changes an IObservable<T> to an IObservable<Notification<T>> and allows errors and completions to be viewed as normal values.
So, as an example, Observable.Return<int>(42) produces a value 42 and a completion, but Observable.Return<int>(42).Materialize() produces a value Notification.CreateOnNext<int>(42), followed by a value Notification.CreateOnCompleted<int>(), followed by a normal completion.
If you have a sequence that produces an error then you effectively get a value Notification.CreateOnError<T>(exception) followed by a normal completion.
This all means that you can change your code like this:
IObservable<Notification<T>> ToObservable<T>(IEnumerable<Task<T>> source)
{
return source.Select(t => t.ToObservable().Materialize()).Merge();
}
Your test code is a little bit complicated for my liking. You should never need to use a SemaphoreSlim nor a Subject in the way that you're using them.
I've written my own test code.
void Main()
{
var r = new Random();
IEnumerable<Task<int>> source =
Enumerable
.Range(0, 10).Select(x => Task.Factory.StartNew(() =>
{
Thread.Sleep(r.Next(10000));
if (x % 3 == 0) throw new NotSupportedException($"Failed on {x}");
return x;
}));
IObservable<Notification<int>> query = source.ToObservable();
query
.Do(x =>
{
if (x.Kind == NotificationKind.OnError)
{
Console.WriteLine(x.Exception.Message);
}
})
.Where(x => x.Kind == NotificationKind.OnNext) // Only care about vales
.Select(x => x.Value)
.Subscribe(x => Console.WriteLine(x), () => Console.WriteLine("Done."));
}
public static class Ex
{
public static IObservable<Notification<T>> ToObservable<T>(this IEnumerable<Task<T>> source)
{
return source.Select(t => t.ToObservable().Materialize()).Merge();
}
}
A typical run of that code produces:
Failed on 3
2
5
4
Failed on 0
Failed on 9
Failed on 6
7
1
8
Done.
The Rx library contains a Merge overload that merges tasks directly and efficiently, instead of converting each task to an intermediate throw-away observable sequence:
// Merges results from all source tasks into a single observable sequence.
public static IObservable<TSource> Merge<TSource>(
this IObservable<Task<TSource>> sources);
You could use this operator for the implementation of the ToObservable method like this:
IObservable<Either<T, Exception>> ToObservable<T>(IEnumerable<Task<T>> source)
{
return source
.Select(async task =>
{
try { return new Either<T, Exception>(await task); }
catch (Exception ex) { return new Either<T, Exception>(ex); }
})
.ToObservable()
.Merge();
}
You can place the ToObservable operator before or after the Select operator, it doesn't make any difference.
Btw there is available a minimalistic library (Try by Stephen Cleary) that contains a Try<T> type, which is similar in functionality to the Either type, but is specialized for having an Exception as the second type (as an Either<T, Exception>). Using this library, you could implement the ToObservable method like this:
IObservable<Try<T>> ToObservable<T>(IEnumerable<Task<T>> source)
{
return source
.Select(task => Try.Create(() => task))
.ToObservable()
.Merge();
}
Here is the definition of the Try.Create method:
// Executes the specified function, and wraps either the result or the exception.
public static Task<Try<T>> Create<T>(Func<Task<T>> func);

Try-Catch with fluent expressions

This LINQ query expression fails with Win32Exception "Access is denied":
Process.GetProcesses().Select(p => p.MainModule.FileName)
And this fails with IOException "The device is not ready":
DriveInfo.GetDrives().Select(d => d.VolumeLabel)
What is the best way to filter out inaccessible objects and avoid exceptions?
Write an extension method!
void Main()
{
var volumeLabels =
DriveInfo
.GetDrives()
.SelectSafe(dr => dr.VolumeLabel);
}
// Define other methods and classes here
public static class LinqExtensions
{
public static IEnumerable<T2> SelectSafe<T,T2>(this IEnumerable<T> source, Func<T,T2> selector)
{
foreach (var item in source)
{
T2 value = default(T2);
try
{
value = selector(item);
}
catch
{
continue;
}
yield return value;
}
}
}
This way you can customise any behaviour you want, and you don't have to create bulky and hacky where clauses, this way you could even get it to return an alternative value if there's an exception.
Update based upon comments: This solution does not work with common enumerators. It does work based upon the enumerators used in the question's examples. Therefore it is not a generic solution. Because it has been written as a generic solution , I advise against using this (to keep things simple). I will keep this answer to enrich the knowledge base.
Another Extension method solution. Why do I prefer it over the existing solutions?
We want to skip elements causing exceptions only. This is the single concern of our LINQ extension.
This implementation does not mix the concern(s) of Select and try/catch.
We can still use existing LINQ methods like Select when needed.
It is reusable: it allows for multiple usages inside a LINQ query.
It follows linq naming conventions: We actually skip similar to Skip and SkipWhile methods.
Usage:
var result = DriveInfo
.GetDrives()
.Select(d => d.VolumeLabel)
.SkipExceptions() // Our extension method
.ToList();
Code:
public static class EnumerableExt
{
// We use the `Skip` name because its implied behaviour equals the `Skip` and `SkipWhile` implementations
public static IEnumerable<TSource> SkipExceptions<TSource>(this IEnumerable<TSource> source)
{
// We use the enumerator to be able to catch exceptions when enumerating the source
using (var enumerator = source.GetEnumerator())
{
// We use a true loop with a break because enumerator.MoveNext can throw the Exception we need to handle
while (true)
{
var exceptionCaught = false;
var currentElement = default(TSource);
try
{
if (!enumerator.MoveNext())
{
// We've finished enumerating. Break to exit the while loop
break;
}
currentElement = enumerator.Current;
}
catch
{
// Ignore this exception and skip this item.
exceptionCaught = true;
}
// Skip this item if we caught an exception. Otherwise return the current element.
if (exceptionCaught) continue;
yield return currentElement;
}
}
}
}
Your answer is the correct one. You can of course try to hide the checking logic inside an extension method.
public static IEnumerable<TElement> WhereSafe<TElement, TInner>(this IEnumerable<TElement> sequence, Func<TElement, TInner> selector)
{
foreach (var element in sequence)
{
try { selector(element); }
catch { continue; }
yield return element;
}
}
Process
.GetProcesses()
.WhereSafe(p => p.MainModule)
.Select(p => p.MainModule.FileName)
Or better so:
public static IEnumerable<TInner> TrySelect<TElement, TInner>(this IEnumerable<TElement> sequence, Func<TElement, TInner> selector)
{
TInner current = default(TInner);
foreach (var element in sequence)
{
try { current = selector(element); }
catch { continue; }
yield return current;
}
}
Process
.GetProcesses()
.TrySelect(p => p.MainModule.FileName)
Insert a WHERE filter (that tries to access any object and absorbs the possible access error) with:
{ try { var x = obj.MyProp; return true; } catch { return false; } }:
First expression:
Process
.GetProcesses()
.Where(p => { try { var x = p.MainModule; return true; } catch { return false; } })
.Select(p => p.MainModule.FileName)
Second expression:
DriveInfo
.GetDrives()
.Where(d => { try { var x = d.VolumeLabel; return true; } catch { return false; } })
.Select(d => d.VolumeLabel)
I would try for the first scenario:
//Declare logger type
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
Process.GetProcesses()
.Where(p => {
try {
var x = p.MainModule;
return true;
}
catch(Win32Exception e2)
{ IgnoreError(); }
})
.Select(p => p.MainModule.FileName)
public static void IgnoreError(Exception e)
{
#if DEBUG
throw e2;
//Save the error track, I prefer log4net
_log.Info("Something bad happened!");
#end if
}
And for the second scenario, I'd rather prefer to use an IF and save the log:
//Somewhere in the begging of your class, in a place whose name I do not care to remember ...
//Declare logger type
private readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public List<string> VolumenLabels()
{
//Return the List<T>
List<string> myVolumeLabels = new List<string>();
//Getting the info
DriveInfo[] allDrives = DriveInfo.GetDrives();
foreach(DriveInfo drive in allDrives)
{
if (drive.IsReady == true)
{
myVolumeLabels.Add(drive.VolumeLabel.ToString());
}
else
{
_log.Info("Check the Drive: " + drive.Name + " the device is not ready.");
}
}
return myVolumeLabels;
}
I hope, I helped a little bit... Have a nice day!

Why there is no expression sequencing operator? [duplicate]

I'm using some functional stuff in C# and keep getting stuck on the fact that List.Add doesn't return the updated list.
In general, I'd like to call a function on an object and then return the updated object.
For example it would be great if C# had a comma operator:
((accum, data) => accum.Add(data), accum)
I could write my own "comma operator" like this:
static T comma(Action a, Func<T> result) {
a();
return result();
}
It looks like it would work but the call site would ugly. My first example would be something like:
((accum, data) => comma(accum.Add(data), ()=>accum))
Enough examples! What's the cleanest way to do this without another developer coming along later and wrinkling his or her nose at the code smell?
I know this as Fluent.
A Fluent example of a List.Add using Extension Methods
static List<T> MyAdd<T>(this List<T> list, T element)
{
list.Add(element);
return list;
}
I know that this thread is very old, but I want to append the following information for future users:
There isn't currently such an operator. During the C# 6 development cycle a semicolon operator was added, as:
int square = (int x = int.Parse(Console.ReadLine()); Console.WriteLine(x - 2); x * x);
which can be translated as follows:
int square = compiler_generated_Function();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int compiler_generated_Function()
{
int x = int.Parse(Console.ReadLine());
Console.WriteLine(x - 2);
return x * x;
}
However, this feature was dropped before the final C# release.
You can do almost exactly the first example naturally using code blocks in C# 3.0.
((accum, data) => { accum.Add(data); return accum; })
This is what Concat http://msdn.microsoft.com/en-us/library/vstudio/bb302894%28v=vs.100%29.aspx is for. Just wrap a single item in an array. Functional code should not mutate the original data. If performance is a concern, and this isn't good enough, then you'll no longer be using the functional paradigm.
((accum, data) => accum.Concat(new[]{data}))
Another technique, straight from functional programming, is as follows. Define an IO struct like this:
/// <summary>TODO</summary>
public struct IO<TSource> : IEquatable<IO<TSource>> {
/// <summary>Create a new instance of the class.</summary>
public IO(Func<TSource> functor) : this() { _functor = functor; }
/// <summary>Invokes the internal functor, returning the result.</summary>
public TSource Invoke() => (_functor | Default)();
/// <summary>Returns true exactly when the contained functor is not null.</summary>
public bool HasValue => _functor != null;
X<Func<TSource>> _functor { get; }
static Func<TSource> Default => null;
}
and make it a LINQ-able monad with these extension methods:
[SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")]
public static class IO {
public static IO<TSource> ToIO<TSource>( this Func<TSource> source) {
source.ContractedNotNull(nameof(source));
return new IO<TSource>(source);
}
public static IO<TResult> Select<TSource,TResult>(this IO<TSource> #this,
Func<TSource,TResult> projector
) =>
#this.HasValue && projector!=null
? New(() => projector(#this.Invoke()))
: Null<TResult>();
public static IO<TResult> SelectMany<TSource,TResult>(this IO<TSource> #this,
Func<TSource,IO<TResult>> selector
) =>
#this.HasValue && selector!=null
? New(() => selector(#this.Invoke()).Invoke())
: Null<TResult>();
public static IO<TResult> SelectMany<TSource,T,TResult>(this IO<TSource> #this,
Func<TSource, IO<T>> selector,
Func<TSource,T,TResult> projector
) =>
#this.HasValue && selector!=null && projector!=null
? New(() => { var s = #this.Invoke(); return projector(s, selector(s).Invoke()); } )
: Null<TResult>();
public static IO<TResult> New<TResult> (Func<TResult> functor) => new IO<TResult>(functor);
private static IO<TResult> Null<TResult>() => new IO<TResult>(null);
}
and now you can use the LINQ comprehensive syntax thus:
using Xunit;
[Fact]
public static void IOTest() {
bool isExecuted1 = false;
bool isExecuted2 = false;
bool isExecuted3 = false;
bool isExecuted4 = false;
IO<int> one = new IO<int>( () => { isExecuted1 = true; return 1; });
IO<int> two = new IO<int>( () => { isExecuted2 = true; return 2; });
Func<int, IO<int>> addOne = x => { isExecuted3 = true; return (x + 1).ToIO(); };
Func<int, Func<int, IO<int>>> add = x => y => { isExecuted4 = true; return (x + y).ToIO(); };
var query1 = ( from x in one
from y in two
from z in addOne(y)
from _ in "abc".ToIO()
let addOne2 = add(x)
select addOne2(z)
);
Assert.False(isExecuted1); // Laziness.
Assert.False(isExecuted2); // Laziness.
Assert.False(isExecuted3); // Laziness.
Assert.False(isExecuted4); // Laziness.
int lhs = 1 + 2 + 1;
int rhs = query1.Invoke().Invoke();
Assert.Equal(lhs, rhs); // Execution.
Assert.True(isExecuted1);
Assert.True(isExecuted2);
Assert.True(isExecuted3);
Assert.True(isExecuted4);
}
When one desires an IO monad that composes but returns only void, define this struct and dependent methods:
public struct Unit : IEquatable<Unit>, IComparable<Unit> {
[CLSCompliant(false)]
public static Unit _ { get { return _this; } } static Unit _this = new Unit();
}
public static IO<Unit> ConsoleWrite(object arg) =>
ReturnIOUnit(() => Write(arg));
public static IO<Unit> ConsoleWriteLine(string value) =>
ReturnIOUnit(() => WriteLine(value));
public static IO<ConsoleKeyInfo> ConsoleReadKey() => new IO<ConsoleKeyInfo>(() => ReadKey());
which readily allow the writing of code fragments like this:
from pass in Enumerable.Range(0, int.MaxValue)
let counter = Readers.Counter(0)
select ( from state in gcdStartStates
where _predicate(pass, counter())
select state )
into enumerable
where ( from _ in Gcd.Run(enumerable.ToList()).ToIO()
from __ in ConsoleWrite(Prompt(mode))
from c in ConsoleReadKey()
from ___ in ConsoleWriteLine()
select c.KeyChar.ToUpper() == 'Q'
).Invoke()
select 0;
where the old C comma operator is readily recognized for what it is: a monadic compose operation.
The true merit of the comprehension syntax is apparent when one attempts to write that fragment in the flunt style:
( Enumerable.Range(0,int.MaxValue)
.Select(pass => new {pass, counter = Readers.Counter(0)})
.Select(_ => gcdStartStates.Where(state => _predicate(_.pass,_.counter()))
.Select(state => state)
)
).Where(enumerable =>
( (Gcd.Run(enumerable.ToList()) ).ToIO()
.SelectMany(_ => ConsoleWrite(Prompt(mode)),(_,__) => new {})
.SelectMany(_ => ConsoleReadKey(), (_, c) => new {c})
.SelectMany(_ => ConsoleWriteLine(), (_,__) => _.c.KeyChar.ToUpper() == 'Q')
).Invoke()
).Select(list => 0);
The extension method is arguably the best solution, but for completeness' sake, don't forget the obvious alternative: a wrapper class.
public class FList<T> : List<T>
{
public new FList<T> Add(T item)
{
base.Add(item);
return this;
}
public new FList<T> RemoveAt(int index)
{
base.RemoveAt(index);
return this;
}
// etc...
}
{
var list = new FList<string>();
list.Add("foo").Add("remove me").Add("bar").RemoveAt(1);
}
I thought it would be interesting to make a version of my wrapper class answer that doesn't require you write the wrapper methods.
public class FList<T> : List<T>
{
public FList<T> Do(string method, params object[] args)
{
var methodInfo = GetType().GetMethod(method);
if (methodInfo == null)
throw new InvalidOperationException("I have no " + method + " method.");
if (methodInfo.ReturnType != typeof(void))
throw new InvalidOperationException("I'm only meant for void methods.");
methodInfo.Invoke(this, args);
return this;
}
}
{
var list = new FList<string>();
list.Do("Add", "foo")
.Do("Add", "remove me")
.Do("Add", "bar")
.Do("RemoveAt", 1)
.Do("Insert", 1, "replacement");
foreach (var item in list)
Console.WriteLine(item);
}
Output:
foo
replacement
bar
EDIT
You can slim down the syntax by exploiting C# indexed properties.
Simply add this method:
public FList<T> this[string method, params object[] args]
{
get { return Do(method, args); }
}
And the call now looks like:
list = list["Add", "foo"]
["Add", "remove me"]
["Add", "bar"]
["RemoveAt", 1]
["Insert", 1, "replacement"];
With the linebreaks being optional, of course.
Just a bit of fun hacking the syntax.

Is there idiomatic C# equivalent to C's comma operator?

I'm using some functional stuff in C# and keep getting stuck on the fact that List.Add doesn't return the updated list.
In general, I'd like to call a function on an object and then return the updated object.
For example it would be great if C# had a comma operator:
((accum, data) => accum.Add(data), accum)
I could write my own "comma operator" like this:
static T comma(Action a, Func<T> result) {
a();
return result();
}
It looks like it would work but the call site would ugly. My first example would be something like:
((accum, data) => comma(accum.Add(data), ()=>accum))
Enough examples! What's the cleanest way to do this without another developer coming along later and wrinkling his or her nose at the code smell?
I know this as Fluent.
A Fluent example of a List.Add using Extension Methods
static List<T> MyAdd<T>(this List<T> list, T element)
{
list.Add(element);
return list;
}
I know that this thread is very old, but I want to append the following information for future users:
There isn't currently such an operator. During the C# 6 development cycle a semicolon operator was added, as:
int square = (int x = int.Parse(Console.ReadLine()); Console.WriteLine(x - 2); x * x);
which can be translated as follows:
int square = compiler_generated_Function();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int compiler_generated_Function()
{
int x = int.Parse(Console.ReadLine());
Console.WriteLine(x - 2);
return x * x;
}
However, this feature was dropped before the final C# release.
You can do almost exactly the first example naturally using code blocks in C# 3.0.
((accum, data) => { accum.Add(data); return accum; })
This is what Concat http://msdn.microsoft.com/en-us/library/vstudio/bb302894%28v=vs.100%29.aspx is for. Just wrap a single item in an array. Functional code should not mutate the original data. If performance is a concern, and this isn't good enough, then you'll no longer be using the functional paradigm.
((accum, data) => accum.Concat(new[]{data}))
Another technique, straight from functional programming, is as follows. Define an IO struct like this:
/// <summary>TODO</summary>
public struct IO<TSource> : IEquatable<IO<TSource>> {
/// <summary>Create a new instance of the class.</summary>
public IO(Func<TSource> functor) : this() { _functor = functor; }
/// <summary>Invokes the internal functor, returning the result.</summary>
public TSource Invoke() => (_functor | Default)();
/// <summary>Returns true exactly when the contained functor is not null.</summary>
public bool HasValue => _functor != null;
X<Func<TSource>> _functor { get; }
static Func<TSource> Default => null;
}
and make it a LINQ-able monad with these extension methods:
[SuppressMessage("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")]
public static class IO {
public static IO<TSource> ToIO<TSource>( this Func<TSource> source) {
source.ContractedNotNull(nameof(source));
return new IO<TSource>(source);
}
public static IO<TResult> Select<TSource,TResult>(this IO<TSource> #this,
Func<TSource,TResult> projector
) =>
#this.HasValue && projector!=null
? New(() => projector(#this.Invoke()))
: Null<TResult>();
public static IO<TResult> SelectMany<TSource,TResult>(this IO<TSource> #this,
Func<TSource,IO<TResult>> selector
) =>
#this.HasValue && selector!=null
? New(() => selector(#this.Invoke()).Invoke())
: Null<TResult>();
public static IO<TResult> SelectMany<TSource,T,TResult>(this IO<TSource> #this,
Func<TSource, IO<T>> selector,
Func<TSource,T,TResult> projector
) =>
#this.HasValue && selector!=null && projector!=null
? New(() => { var s = #this.Invoke(); return projector(s, selector(s).Invoke()); } )
: Null<TResult>();
public static IO<TResult> New<TResult> (Func<TResult> functor) => new IO<TResult>(functor);
private static IO<TResult> Null<TResult>() => new IO<TResult>(null);
}
and now you can use the LINQ comprehensive syntax thus:
using Xunit;
[Fact]
public static void IOTest() {
bool isExecuted1 = false;
bool isExecuted2 = false;
bool isExecuted3 = false;
bool isExecuted4 = false;
IO<int> one = new IO<int>( () => { isExecuted1 = true; return 1; });
IO<int> two = new IO<int>( () => { isExecuted2 = true; return 2; });
Func<int, IO<int>> addOne = x => { isExecuted3 = true; return (x + 1).ToIO(); };
Func<int, Func<int, IO<int>>> add = x => y => { isExecuted4 = true; return (x + y).ToIO(); };
var query1 = ( from x in one
from y in two
from z in addOne(y)
from _ in "abc".ToIO()
let addOne2 = add(x)
select addOne2(z)
);
Assert.False(isExecuted1); // Laziness.
Assert.False(isExecuted2); // Laziness.
Assert.False(isExecuted3); // Laziness.
Assert.False(isExecuted4); // Laziness.
int lhs = 1 + 2 + 1;
int rhs = query1.Invoke().Invoke();
Assert.Equal(lhs, rhs); // Execution.
Assert.True(isExecuted1);
Assert.True(isExecuted2);
Assert.True(isExecuted3);
Assert.True(isExecuted4);
}
When one desires an IO monad that composes but returns only void, define this struct and dependent methods:
public struct Unit : IEquatable<Unit>, IComparable<Unit> {
[CLSCompliant(false)]
public static Unit _ { get { return _this; } } static Unit _this = new Unit();
}
public static IO<Unit> ConsoleWrite(object arg) =>
ReturnIOUnit(() => Write(arg));
public static IO<Unit> ConsoleWriteLine(string value) =>
ReturnIOUnit(() => WriteLine(value));
public static IO<ConsoleKeyInfo> ConsoleReadKey() => new IO<ConsoleKeyInfo>(() => ReadKey());
which readily allow the writing of code fragments like this:
from pass in Enumerable.Range(0, int.MaxValue)
let counter = Readers.Counter(0)
select ( from state in gcdStartStates
where _predicate(pass, counter())
select state )
into enumerable
where ( from _ in Gcd.Run(enumerable.ToList()).ToIO()
from __ in ConsoleWrite(Prompt(mode))
from c in ConsoleReadKey()
from ___ in ConsoleWriteLine()
select c.KeyChar.ToUpper() == 'Q'
).Invoke()
select 0;
where the old C comma operator is readily recognized for what it is: a monadic compose operation.
The true merit of the comprehension syntax is apparent when one attempts to write that fragment in the flunt style:
( Enumerable.Range(0,int.MaxValue)
.Select(pass => new {pass, counter = Readers.Counter(0)})
.Select(_ => gcdStartStates.Where(state => _predicate(_.pass,_.counter()))
.Select(state => state)
)
).Where(enumerable =>
( (Gcd.Run(enumerable.ToList()) ).ToIO()
.SelectMany(_ => ConsoleWrite(Prompt(mode)),(_,__) => new {})
.SelectMany(_ => ConsoleReadKey(), (_, c) => new {c})
.SelectMany(_ => ConsoleWriteLine(), (_,__) => _.c.KeyChar.ToUpper() == 'Q')
).Invoke()
).Select(list => 0);
The extension method is arguably the best solution, but for completeness' sake, don't forget the obvious alternative: a wrapper class.
public class FList<T> : List<T>
{
public new FList<T> Add(T item)
{
base.Add(item);
return this;
}
public new FList<T> RemoveAt(int index)
{
base.RemoveAt(index);
return this;
}
// etc...
}
{
var list = new FList<string>();
list.Add("foo").Add("remove me").Add("bar").RemoveAt(1);
}
I thought it would be interesting to make a version of my wrapper class answer that doesn't require you write the wrapper methods.
public class FList<T> : List<T>
{
public FList<T> Do(string method, params object[] args)
{
var methodInfo = GetType().GetMethod(method);
if (methodInfo == null)
throw new InvalidOperationException("I have no " + method + " method.");
if (methodInfo.ReturnType != typeof(void))
throw new InvalidOperationException("I'm only meant for void methods.");
methodInfo.Invoke(this, args);
return this;
}
}
{
var list = new FList<string>();
list.Do("Add", "foo")
.Do("Add", "remove me")
.Do("Add", "bar")
.Do("RemoveAt", 1)
.Do("Insert", 1, "replacement");
foreach (var item in list)
Console.WriteLine(item);
}
Output:
foo
replacement
bar
EDIT
You can slim down the syntax by exploiting C# indexed properties.
Simply add this method:
public FList<T> this[string method, params object[] args]
{
get { return Do(method, args); }
}
And the call now looks like:
list = list["Add", "foo"]
["Add", "remove me"]
["Add", "bar"]
["RemoveAt", 1]
["Insert", 1, "replacement"];
With the linebreaks being optional, of course.
Just a bit of fun hacking the syntax.

Categories

Resources