score:13
Not an answer to your question, but rather some musings on your design. We strongly considered adding such a feature to C# 4 but cut it because we did not have the time and resources available.
The problem with the query comprehension syntax is, as you note, that it is ugly to mix the "fluent" and "comprehension" syntaxes. You want to know how many different last names your customers have in London and you end up writing this ugly thing with parentheses:
d = (from c in customers
where c.City == "London"
select c.LastName)
.Distinct()
.Count();
Yuck.
We considered adding a new contextual keyword to the comprehension syntax. Let's say for the sake of argument that the keyword is "with". You could then say:
d = from c in customers
where c.City == "London"
select c.LastName
with Distinct()
with Count();
and the query comprehension rewriter would rewrite that into the appropriate fluent syntax.
I really like this feature but it did not make the cut for C# 4 or 5. It would be nice to get it into a hypothetical future version of the language.
As always, Eric's musing about hypothetical features of unannounced products that might never exist are for entertainment purposes only.
score:3
On idea is that you could write your own query provider that wraps the version in System.Linq
and then calls ToArray
in its Select
method. Then you would just have a using YourNamespace;
instead of using System.Linq
.
Roslyn does not allow you to extend the syntax of C#, but you can write a SyntaxRewriter
that changes the semantics of a C# program as a rebuild step.
score:2
As others said, Roslyn is not what you probably think it is. It can't be used to extend C#.
All of the following code should be considered more brainstorming and less recommendation. It changes how LINQ behaves in unexpected ways and you should think really hard before using anything like it.
One way to solve this would be to modify the select
clause like this:
int count = from i in Enumerable.Range(0, 10)
where i % 2 == 0
select new Count();
The implementation could look like this:
public class Count
{}
public static class LinqExtensions
{
public static int Select<T>(
this IEnumerable<T> source, Func<T, Count> selector)
{
return source.Count();
}
}
If you put anything that isn't Count
in the select
, it would behave as usual.
Doing something similar for arrays would take more work, since you need the select
to specify both that you want an array and the selector of items you want in there, but it's doable. Or you could use two select
s: one chooses the item and the other says you want an array.
Another option (similar to Kevin's suggestion) would be to have extension method like AsCount()
which you could use like this:
int count = from i in Enumerable.Range(0, 10).AsCount()
where i % 2 == 0
select i;
You could implement it like this:
public static class LinqExtensions
{
public static Countable<T> AsCount<T>(this IEnumerable<T> source)
{
return new Countable<T>(source);
}
}
public class Countable<T>
{
private readonly IEnumerable<T> m_source;
public Countable(IEnumerable<T> source)
{
m_source = source;
}
public Countable<T> Where(Func<T, bool> predicate)
{
return new Countable<T>(m_source.Where(predicate));
}
public Countable<TResult> Select<TResult>(Func<T, TResult> selector)
{
return new Countable<TResult>(m_source.Select(selector));
}
// other LINQ methods
public static implicit operator int(Countable<T> countable)
{
return countable.m_source.Count();
}
}
I'm not sure I like it this way. Especially the implicit cast feels wrong, but I think there is no other way.
Source: stackoverflow.com
Related Articles
- available options for 'fake' linq comprehension syntax keywordsin C#?
- LINQ Source Code Available
- How to Convert LINQ Comprehension Query Syntax to Method Syntax using Lambda
- Syntax to execute code block inside Linq query?
- creating Linq to sqlite dbml from DbLinq source code
- Understanding the various options for runtime code generation in C# (Roslyn, CodeDom, Linq Expressions, ...?)
- source code for LINQ 101 samples
- c# Linq or code to extract groups from a single list of source data
- Convert string[] to int[] in one line of code using LINQ
- Code equivalent to the 'let' keyword in chained LINQ extension method calls
- Linq Syntax - Selecting multiple columns
- Linq code to select one item
- Using LINQ extension method syntax on a MatchCollection
- Is there a C# LINQ syntax for the Queryable.SelectMany() method?
- LINQ - Query syntax vs method chains & lambda
- How are people unit testing code that uses Linq to SQL
- Python's list comprehension vs .NET LINQ
- LINQ group by expression syntax
- LINQ syntax where string value is not null or empty
- How does LINQ expression syntax work with Include() for eager loading
- .NET LINQ query syntax vs method chain
- left outer join in lambda/method syntax in Linq
- What's the equivalent VB.NET syntax for anonymous types in a LINQ statement?
- Linq syntax for OrderBy with custom Comparer<T>
- GroupBy with linq method syntax (not query syntax)
- LINQ Lambda vs Query Syntax Performance
- LINQ query to perform a projection, skipping or wrapping exceptions where source throws on IEnumerable.GetNext()
- AsNoTracking using LINQ Query syntax instead of Method syntax
- Is there a LINQ syntax for the (T, int) overloads of Where and Select?
- Differences in LINQ syntax between VB.Net and C#
- Linq - Sum with isnull
- Using LINQ to order to different properties of an object
- LINQ to Entities - method cannot be translated into a store expression
- Linq to sql alias fails
- Using GroupBy in Linq: Client side GroupBy is not supported
- Porting OnPropertyChanged from C# to VB.Net
- Append XML to file without writing it from scratch?
- Linq compare XML Values
- how to return null values from a dateTime column in linq
- Get ID from another table
- Change one field in an array using linq
- Linq-to-Sql query with group by
- EF Core include an ICollection<T> with a filter on the collection's referenced object
- Gridview show empty row
- find rows with same value using LINQ
- Function to create and modify xml
- Getting an Average over Multiple Collections in LINQ
- Linq: Difference between 2 DateTimes in TimeSpan
- EF Core LINQ GROUPBY Then Select to get more than one properties of the entity
- How to reorder ITestCaseCollection using C#