Replacing Exceptions With Either/Maybe/Option - c#

I came across this dead end while trying to replace exceptions with either monad in c#.
Which leads me to think maybe it is not only language specific problem and more technique related missing feature.
Let me try to re-explain it more globally:
Given:
I have a 3rd party function( a function that is imported into my code and I have no access to) which receives a lazy list (c# IEnumerable,f# Seq...) and consume it
I Want:
To apply a function (LINQ select,map...) on the method's lazy list argument and will take each element of the list (lazily) and will do computation that might fail (throwing an exception or returning Error/Either).
The list to be consumed only "inside" the 3rd party function, I don't want to have to iterate over each element more then once.
With Exceptions/side effects this can be achieved easily with throwing exception from the select, map functions if error was found, this will stop the execution "inside" the 3rd party function. Then I could handle the exception outside of it (without the 3rd party being "aware" of my error handling), leaving the responsibility of the error handling to me.
While with Either it does not seem to be possible to get the same behavior without altering the 3rd party function. Intuitively I was trying to convert the list from the list of Eithers to Either of list, but this can be done only by consuming the list with functions. Like, aggregate or reduce (does Haskell's Sequence function act the same?).
All this leads me to the question are Maybes/Eithers or Error as return type, missing this behavior? Is there another way to achive the same thing with them?

As far as I can tell, Haskell Either is isomorphic to C#/Java-style exceptions, meaning that there's a translation from Either-based code to exception-based code, and vice versa. I'm not quite sure about this, though, as there may be some edge cases that I'm not aware of.
On the other hand, what I am sure of is that Either () a is isomorphic to Maybe a, so in the following, I'm going to stick with Either and ignore Maybe.
What you can do with exceptions in C#, you can also do with Either. The default in C# is to do no error handling1:
public IEnumerable<TResult> NoCatch<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
return source.Select(selector);
}
This will iterate over source until an exception happens. If no exception is thrown, it'll return IEnumerable<TResult>, but if an exception is thrown by selector, the entire method throws an exception as well. However, if elements of source were handled before an exception was thrown, and there were side-effects, that work remains done.
You can do the same in Haskell using sequence:
noCatch :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
noCatch f = sequence . fmap f
If f is a function that returns Either, then it behaves in the same way:
*Answer> noCatch (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 2]
Right [1,3,5,2]
*Answer> noCatch (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
Left 11
As you can see, if no Left value is ever returned, you get a Right case back, with all the mapped elements. If just one Left case is returned, you get that, and no further processing is done.
You could also imagine that you have a C# method that suppresses individual exceptions:
public IEnumerable<TResult> Suppress<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
foreach (var x in source)
try { yield selector(x) } catch {}
}
In Haskell, you could do this with Either:
filterRight :: (a -> Either e b) -> [a] -> [b]
filterRight f = rights . fmap f
This returns all the Right values, and ignores the Left values:
*Answer> filterRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
[1,3,5,2]
You can also write a method that processes the input until the first exception is thrown (if any):
public IEnumerable<TResult> ProcessUntilException<TResult, T>(
IEnumerable<T> source, Func<T, TResult> selector)
{
var exceptionHappened = false;
foreach (var x in source)
{
if (!exceptionHappened)
try { yield selector(x) } catch { exceptionHappened = true }
}
}
Again, you can achieve the same effect with Haskell:
takeWhileRight :: (a -> Either e b) -> [a] -> [Either e b]
takeWhileRight f = takeWhile isRight . fmap f
Examples:
*Answer> takeWhileRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 11, 2, 12]
[Right 1,Right 3,Right 5]
*Answer> takeWhileRight (\i -> if i < 10 then Right i else Left i) [1, 3, 5, 2]
[Right 1,Right 3,Right 5,Right 2]
As you can see, however, both the C# examples and the Haskell examples need to be aware of the style of error-handling. While you can translate between the two styles, you can't use one with a method/function that expects the other.
If you have a third-party C# method that expects exception handling to be the way things are done, you can't pass it a sequence of Either values and hope that it can deal with it. You'd have to modify the method.
The converse isn't quite true, though, because exception-handling is built into C# (and Haskell as well, in fact); you can't really opt out of exception-handling in such languages. Imagine, however, a language that doesn't have built-in exception-handling (PureScript, perhaps?), and this would be true as well.
1 C# code may not compile.

I haven't got a compiler handy, but you may want to check my language-ext project. It's a functional base class library for C#.
For your needs it has:
Seq<A> which is a cons like lazy enumerable which will only evaluate once
Try<A> which is a delegate based monad which allows you to capture exceptions from third party code
Other common error handling monads: Option<A>, Either<L, R>, etc.
Bonus variants of those monads: OptionAsync<A>, TryOption<A>, TryAsync<A>, TryOptionAsync<A>
Ability to easily convert between those types: ToOption(), ToEither(), etc.
To apply a function (LINQ select,map...) on the method's lazy list argument and will take each element of the list (lazily) and will do computation that might fail (throwing an exception or returning Error/Either).
The list to be consumed only "inside" the 3rd party function, I don't want to have to iterate over each element more then once.
This is a little unclear of the actual goal. In language-ext you could do this:
using LanguageExt;
using static LanguageExt.Prelude;
// Dummy lazy enumerable
IEnumerable<int> Values()
{
for(int i = 0; i < 100; i++)
{
yield return UnreliableExternalFunc(i);
}
}
// Convert to a lazy sequence
Seq<int> seq = Seq(Values());
// Invoke external function that takes an IEnumerable
ExternalFunction(seq);
// Calling it again won't evaluate it twice
ExternalFunction(seq);
But if the Values() function threw an exception then it would end its yielding and would return. So you'd ideally have this:
// Dummy lazy enumerable
IEnumerable<Try<int>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i));
}
}
Try is the constructor function for the Try monad. So your result would be a sequence of Try thunks. If you don't care about the exception you could convert it to an Option
// Dummy lazy enumerable
IEnumerable<Option<int>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i)).ToOption();
}
}
The you could access all successes via:
var validValues = Values().Somes();
Or you could instead use Either:
// Dummy lazy enumerable
IEnumerable<Either<Exception, A>> Values()
{
for(int i = 0; i < 100; i++)
{
yield return Try(() => UnreliableExternalFunc(i)).ToEither();
}
}
Then you can get the valid results thus:
var seq = Seq(Values());
var validValues = seq.Rights();
And the errors:
var errors = seq.Lefts();
I converted it to a Seq so it doesn't evaluate twice.
One way or another, if you want to catch an exception that happens during the lazy evaluation of the enumerable, then you will need to wrap each value. If the exception can occur from the usage of the lazy value, but within a function then your only hope is to surround it with a Try:
// Convert to a lazy sequence
Seq<int> seq = Seq(Values()); // Values is back to returning IEnumerable<int>
// Invoke external function that takes an IEnumerable
var res = Try(() => ExternalFunction(seq)).IfFail(Seq<int>.Empty);
// Calling it again won't evaluate it twice
ExternalFunction(seq);
Intuitively I was trying to convert the list from the list of Eithers to Either of list, but this can be done only by consuming the list with functions. Like, aggregate or reduce (does Haskell's Sequence function act the same?).
You can do this in language-ext like so:
IEnumerable<Either<L, R>> listOfEithers = ...;
Either<L, IEnumerable<R>> eitherList = listOfEithers.Sequence();
Traverse is also supported:
Either<L, IEnumerable<R>> eitherList = listOfEithers.Traverse(x => map(x));
All combinations of monads support Sequence() and Traverse; so you could do it with a Seq<Either<L, R>> to get a Either<L, Seq<R>>, which would guarantee that the lazy sequence isn't invoked multiple times. Or a Seq<Try<A>> to get a Try<Seq<A>>, or any of the async variants for concurrent sequencing and traversal.
I'm not sure if any of this is covering what you're asking, the question is a bit broad. A more specific example would be useful.

Related

Function IIF, how to make it take 2N + 1 arguments of logical expressions?, C #

In Visual Basic, there is this IIF Function, as in Crystal Report, etc ...
In C # itself, this function does not exist, but it is the same as doing something like this:
bool a = true;
string b = a ? "is_True" : "is_False";
But for the code to be a bit easier to read I wanted to do it as a function for C #, leaving it like this:
public static T IIf<T>(bool expression, T truePart, T falsePart)
{
     return expression ? truePart : falsePart;
}
Or to not operate with the real values ​​can also be done using delegates, to access the necessary values:
public static T IIf<T>(bool expression, Func<T> truePart, Func<T> falsePart)
{
    return expression ? truePart() : falsePart();
}
So far this works well ...
But how can I modify this function so I can take 2N + 1 arguments?
(N - the number of logical expressions specified)
Example the desired result:
Each odd argument specifies a logical expression;
Each even argument specifies the value that is returned if the previous expression evaluates to true;
The last argument specifies the value that is returned if the previously evaluated logical expressions yielded false.
int value = IIf(Name = "Joel", 1, Name = "Peter", 2, Name = "Maria", 3, 4);
Can someone give me a hand with this?
Environment: C # - Visual Studio 2017
First off, as noted in the comments, this is a bad idea. Newer versions of C# already support pattern-matching switches as a built-in feature of the language; use it.
Second, this is a bad idea because the API of "argument, case1, result1, case2, result2, ..." has a signature that is hard to express in the C# type system.
Were I forced to implement such an API, I would suggest using tuples:
public static R Switch<A, R>(
A item,
R theDefault,
params (A, R)[] cases )
{
foreach(var c in cases)
if (item.Equals(c.Item1))
return c.Item2;
return theDefault;
}
Or, make a helpful utility method and use it:
public static T FirstOrDefault(
this IEnumerable<T> items,
T theDefault,
Func<T, bool> predicate)
{
foreach(var i in items.Where(predicate))
return i;
return theDefault;
}
public static R Switch<A, R>(
A item,
R theDefault,
params (A, R)[] cases ) =>
cases.FirstOrDefault(
(item, theDefault),
c => item.Equals(c.Item1)).Item2;
If you cannot use tuples because you're using an older version of C#, you could make your own pair type or use the key-value pair type.
But just do not go there. If you need a switch, write a switch. If you need a dictionary, write a dictionary.
If you want to preserve the order of your parameters, which presumably you do if you're trying so hard to make the function replicate what you've seen elsewhere, then you can write something like this:
public T IIf<T>(params object[] objects) {
for(var i = 0; i < objects.Length - 1; i += 2)
if((bool)objects[i])
return (T)objects[i+1];
return (T)objects[objects.Length - 1];
}
But it's a good lesson in why you would avoid something like this. Firstly, you have to explicitly declare the type you're working with. So you'd have to use it like this:
var value = IIf<int>(Name == "Joel", 1, Name == "Peter", 2, Name == "Maria", 3, 4);
Notice the passing of 'int' as a type parameter. You can avoid that by changing the order of the parameters so that the default comes first.
But, if you're just willing to adopt a personal pattern, the nested ternary syntax can be quite readable:
var value =
Name == "Joel" ? 1
: Name == "Peter" ? 2
: Name == "Maria" ? 3
: 4;
If you don't feel it's readable, then it's just because it takes some getting used to. Imagine going the other way, from a C# developer to VB, and seeing 'IIF'. You'd be thinking, "why do they add the extra 'I' in 'IF'?". I should make a function "IF" that emulates "IIF". But that would be a bad idea, wouldn't it?

Linq late binding confusion

Can someone please explain me what I am missing here. Based on my basic understanding linq result will be calculated when the result will be used and I can see that in following code.
static void Main(string[] args)
{
Action<IEnumerable<int>> print = (x) =>
{
foreach (int i in x)
{
Console.WriteLine(i);
}
};
int[] arr = { 1, 2, 3, 4, 5 };
int cutoff = 1;
IEnumerable<int> result = arr.Where(x => x < cutoff);
Console.WriteLine("First Print");
cutoff = 3;
print(result);
Console.WriteLine("Second Print");
cutoff = 4;
print(result);
Console.Read();
}
Output:
First Print
1
2
Second Print
1
2
3
Now I changed the
arr.Where(x => x < cutoff);
to
IEnumerable<int> result = arr.Take(cutoff);
and the output is as follow.
First Print
1
Second Print
1
Why with Take, it does not use the current value of the variable?
The behavior your seeing comes from the different way in which the arguments to the LINQ functions are evaluated. The Where method recieves a lambda which captures the value cutoff by reference. It is evaluated on demand and hence sees the value of cutoff at that time.
The Take method (and similar methods like Skip) take an int parameter and hence cutoff is passed by value. The value used is the value of cutoff at the moment the Take method is called, not when the query is evaluated
Note: The term late binding here is a bit incorrect. Late binding generally refers to the process where the members an expression binds to are determined at runtime vs. compile time. In C# you'd accomplish this with dynamic or reflection. The behavior of LINQ to evaluate it's parts on demand is known as delayed execution.
There's a few different things getting confused here.
Late-binding: This is where the meaning of code is determined after it was compiled. For example, x.DoStuff() is early-bound if the compiler checks that objects of x's type have a DoStuff() method (considering extension methods and default arguments too) and then produces the call to it in the code it outputs, or fails with a compiler error otherwise. It is late-bound if the search for the DoStuff() method is done at run-time and throws a run-time exception if there was no DoStuff() method. There are pros and cons to each, and C# is normally early-bound but has support for late-binding (most simply through dynamic but the more convoluted approaches involving reflection also count).
Delayed execution: Strictly speaking, all Linq methods immediately produce a result. However, that result is an object which stores a reference to an enumerable object (often the result of the previous Linq method) which it will process in an appropriate manner when it is itself enumerated. For example, we can write our own Take method as:
private static IEnumerable<T> TakeHelper<T>(IEnumerable<T> source, int number)
{
foreach(T item in source)
{
yield return item;
if(--number == 0)
yield break;
}
}
public static IEnumerable<T> Take<T>(this IEnumerable<T> source, int number)
{
if(source == null)
throw new ArgumentNullException();
if(number < 0)
throw new ArgumentOutOfRangeException();
if(number == 0)
return Enumerable.Empty<T>();
return TakeHelper(source, number);
}
Now, when we use it:
var taken4 = someEnumerable.Take(4);//taken4 has a value, so we've already done
//something. If it was going to throw
//an argument exception it would have done so
//by now.
var firstTaken = taken4.First();//only now does the object in taken4
//do the further processing that iterates
//through someEnumerable.
Captured variables: Normally when we make use of a variable, we make use of how its current state:
int i = 2;
string s = "abc";
Console.WriteLine(i);
Console.WriteLine(s);
i = 3;
s = "xyz";
It's pretty intuitive that this prints 2 and abc and not 3 and xyz. In anonymous functions and lambda expressions though, when we make use of a variable we are "capturing" it as a variable, and so we will end up using the value it has when the delegate is invoked:
int i = 2;
string s = "abc";
Action λ = () =>
{
Console.WriteLine(i);
Console.WriteLine(s);
};
i = 3;
s = "xyz";
λ();
Creating the λ doesn't use the values of i and s, but creates a set of instructions as to what to do with i and s when λ is invoked. Only when that happens are the values of i and s used.
Putting it all together: In none of your cases do you have any late-binding. That is irrelevant to your question.
In both you have delayed execution. Both the call to Take and the call to Where return enumerable objects which will act upon arr when they are enumerated.
In only one do you have a captured variable. The call to Take passes an integer directly to Take and Take makes use of that value. The call to Where passes a Func<int, bool> created from a lambda expression, and that lambda expression captures an int variable. Where knows nothing of this capture, but the Func does.
That's the reason the two behave so differently in how they treat cutoff.
Take doesn't take a lambda, but an integer, as such it can't change when you change the original variable.

Find sequence in IEnumerable<T> using Linq

What is the most efficient way to find a sequence within a IEnumerable<T> using LINQ
I want to be able to create an extension method which allows the following call:
int startIndex = largeSequence.FindSequence(subSequence)
The match must be adjacent and in order.
Here's an implementation of an algorithm that finds a subsequence in a sequence. I called the method IndexOfSequence, because it makes the intent more explicit and is similar to the existing IndexOf method:
public static class ExtensionMethods
{
public static int IndexOfSequence<T>(this IEnumerable<T> source, IEnumerable<T> sequence)
{
return source.IndexOfSequence(sequence, EqualityComparer<T>.Default);
}
public static int IndexOfSequence<T>(this IEnumerable<T> source, IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
var seq = sequence.ToArray();
int p = 0; // current position in source sequence
int i = 0; // current position in searched sequence
var prospects = new List<int>(); // list of prospective matches
foreach (var item in source)
{
// Remove bad prospective matches
prospects.RemoveAll(k => !comparer.Equals(item, seq[p - k]));
// Is it the start of a prospective match ?
if (comparer.Equals(item, seq[0]))
{
prospects.Add(p);
}
// Does current character continues partial match ?
if (comparer.Equals(item, seq[i]))
{
i++;
// Do we have a complete match ?
if (i == seq.Length)
{
// Bingo !
return p - seq.Length + 1;
}
}
else // Mismatch
{
// Do we have prospective matches to fall back to ?
if (prospects.Count > 0)
{
// Yes, use the first one
int k = prospects[0];
i = p - k + 1;
}
else
{
// No, start from beginning of searched sequence
i = 0;
}
}
p++;
}
// No match
return -1;
}
}
I didn't fully test it, so it might still contain bugs. I just did a few tests on well-known corner cases to make sure I wasn't falling into obvious traps. Seems to work fine so far...
I think the complexity is close to O(n), but I'm not an expert of Big O notation so I could be wrong... at least it only enumerates the source sequence once, whithout ever going back, so it should be reasonably efficient.
The code you say you want to be able to use isn't LINQ, so I don't see why it need be implemented with LINQ.
This is essentially the same problem as substring searching (indeed, an enumeration where order is significant is a generalisation of "string").
Since computer science has considered this problem frequently for a long time, so you get to stand on the shoulders of giants.
Some reasonable starting points are:
http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm
http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm
http://en.wikipedia.org/wiki/Rabin-karp
Even just the pseudocode in the wikipedia articles is enough to port to C# quite easily. Look at the descriptions of performance in different cases and decide which cases are most likely to be encountered by your code.
I understand this is an old question, but I needed this exact method and I wrote it up like so:
public static int ContainsSubsequence<T>(this IEnumerable<T> elements, IEnumerable<T> subSequence) where T: IEquatable<T>
{
return ContainsSubsequence(elements, 0, subSequence);
}
private static int ContainsSubsequence<T>(IEnumerable<T> elements, int index, IEnumerable<T> subSequence) where T: IEquatable<T>
{
// Do we have any elements left?
bool elementsLeft = elements.Any();
// Do we have any of the sub-sequence left?
bool sequenceLeft = subSequence.Any();
// No elements but sub-sequence not fully matched
if (!elementsLeft && sequenceLeft)
return -1; // Nope, didn't match
// No elements of sub-sequence, which means even if there are
// more elements, we matched the sub-sequence fully
if (!sequenceLeft)
return index - subSequence.Count(); // Matched!
// If we didn't reach a terminal condition,
// check the first element of the sub-sequence against the first element
if (subSequence.First().Equals(e.First()))
// Yes, it matched - move onto the next. Consume (skip) one element in each
return ContainsSubsequence(elements.Skip(1), index + 1 subSequence.Skip(1));
else
// No, it didn't match. Try the next element, without consuming an element
// from the sub-sequence
return ContainsSubsequence(elements.Skip(1), index + 1, subSequence);
}
Updated to not just return if the sub-sequence matched, but where it started in the original sequence.
This is an extension method on IEnumerable, fully lazy, terminates early and is far more linq-ified than the currently up-voted answer. Bewarned, however (as #wai-ha-lee points out) it is recursive and creates a lot of enumerators. Use it where applicable (performance/memory). This was fine for my needs, but YMMV.
You can use this library called Sequences to do that (disclaimer: I'm the author).
It has a IndexOfSlice method that does exactly what you need - it's an implementation of the Knuth-Morris-Pratt algorithm.
int startIndex = largeSequence.AsSequence().IndexOfSlice(subSequence);
UPDATE:
Given the clarification of the question my response below isn't as applicable. Leaving it for historical purposes.
You probably want to use mySequence.Where(). Then the key is to optimize the predicate to work well in your environment. This can vary quite a bit depending on your requirements and typical usage patterns.
It is quite possible that what works well for small collections doesn't scale well for much larger collections depending on what type T is.
Of course, if the 90% use is for small collections then optimizing for the outlier large collection seems a bit YAGNI.

Non-determinstic choice with amb-operator

Is it possible to implement McCarthy's amb-operator for non-deterministic choice in C#?
Apparently .NET lacks continuation support but yield return could be useful. Would this be possible in other static .NET-languages like F#?
Yes, yield return does a form of continuation. Although for many useful cases, Linq provides functional operators that allow you to plug together a lazy sequence generator, so in fact in C# 3 it isn't necessary to use yield return so much (except when adding more Linq-style extensions of your own to plug gaps in the library, e.g. Zip, Unfold).
In the example we factorise an integer by brute force. Essentially the same example in C# can be done with the built-in Linq operators:
var factors = Enumerable.Range(2, 100)
.Join(Enumerable.Range(2, 100),
n => 1, n => 1, (i, j) => new { i, j })
.First(v => v.i*v.j == 481);
Console.WriteLine("Factors are " + factors.i + ", " + factors.j);
Here the starting points are my two calls to Enumerable.Range, which is built-in to Linq but you could implement yourself as:
IEnumerable<int> Range(int start, int stop)
{
for (int n = start; n < stop; n++)
yield return n;
}
There are two odd parameters, the n => 1, n => 1 parameters to Join. I'm picking 1 as the key value for Join to use when matching up items, hence all combinations will match and so I get to test every combination of numbers from the ranges.
Then I turn the pair of values into a kind of tuple (an anonymous type) with:
(i, j) => new { i, j })
Finally, I pick the first such tuple for which my test is satisfied:
.First(v => v.i*v.j == 481);
Update
The code inside the call to First need not be merely a short test expression. It can be a whole lot of imperative code which needs to be "restarted" if the test fails:
.First(v =>
{
Console.WriteLine("Aren't lambdas powerful things?");
return v.i*v.j == 481;
);
So the part of the program that potentially needs to be restarted with different values goes in that lambda. Whenever that lambda wants to restart itself with different values, it just returns false - the equivalent of calling amb with no arguments.
This is not an answer to your question, but it may get you what you want.
amb is used for nondeterministic computing. As you may know, Prolog is a nondeterministic language using the notion of unification to bind values to variables (basically what amb ends up doing).
There IS an implementation of this functionality in C#, called YieldProlog. As you guessed, the yield operator is an important requisite for this.
http://yieldprolog.sourceforge.net/

Multidimensional arrays do not implement IEnumerable<T>, or do they?

For the reasons that I still do not understand (see this SO question) multidimensional arrays in CLR do not implement IEnumerable<T>. So the following does not compile:
var m = new int[2,2] {{1, 2}, {3, 4}};
var q = from e in m select e;
Then how come that this works just fine in VB.NET?
Sub Main()
Dim m(,) As Integer = {{1, 2}, {3, 4}}
Dim q = From e In m Select e
For Each i In q
Console.WriteLine(i)
Next
End Sub
Update:
The following code works because the C# compiler replaces the foreach with for loops to go through each dimension.
foreach(var e in m)
Console.WriteLine(e);
becomes
int[,] numArray3 = new int[,] { { 2, 2 }, { 3, 3 } };
int upperBound = numArray3.GetUpperBound(0);
int num4 = numArray3.GetUpperBound(1);
for (int i = numArray3.GetLowerBound(0); i <= upperBound; i++)
{
for (int j = numArray3.GetLowerBound(1); j <= num4; j++)
{
int num = numArray3[i, j];
Console.WriteLine(num);
}
}
The query works in VB.Net because it gets transformed into
IEnumerable<object> q = m.Cast<object>().Select<object, object>(o => o);
This works because you can call Cast<TResult>() on IEnumerable, which [*,*] implements.
The LINQ query doesn't work in C# because of the different approach the C# and VB.Net designers took. VB.Net takes a more hand holding approach and fixes your mistake and converts IEnumerable to IEnumerable<object> so it can be used.
In C#, you can simulate this by using
var q = from e in m.Cast<object>() select e;
There are two reasons they don't implement it natively in C#:
There's more than one way you could do it. Do you want each 'cell', or do you want each 'row'? And how do you define 'row': [], IEnumerable, other? What if there are more than two dimensions? As soon as they pick one way, an army of developers will tell them they should have done it a different way.
Thanks to iterator blocks and the yield keyword, it just so easy to implement your own that's specific to your need at the time. Of course, that's a C# construct, but it's not that much harder in VB.
The MSDN page for Array includes this:
Important Note:
In the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time,
Note the final words in the quote... it appears this generation does not happen for multi-dimensional arrays (so a documentation bug).
But as others have noted, what would T be? A good case can be made for T[] (or, these days with LINQ, IEnumerable<T>).
In the end, if you want to iterate all the array's members just stick with IEnumerable and Cast<T> extension. Otherwise easy to write your own.
Tip: instead of Cast<object>() use a typed range variable
Samuel stated:
In C#, you can simulate this by using
var q = from e in m.Cast<object>() select e;
// q is of type IEnumerable<object>
which is of course correct as far as mimicking VB in C# is concerned, but you would loose your type information. Instead, it is much easier and as it turns out, slightly better readable, to simply declare your range variable.
The following compiles, performs better, is type safe and does not loose type information:
var m = new int[2, 2] { { 1, 2 }, { 3, 4 } };
var q = from int e in m select e;
// q is of type IEnumerable<int>
In the original suggestion, you would have an IEnumerable<object>, using int e you change that into IEnumerable<int>, which has its advantages.

Categories

Resources