可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Saw a post about hidden features in C# but not a lot of people have written linq/lambdas example so... I wonder...
What's the coolest (as in the most elegant) use of the C# LINQ and/or Lambdas/anonymous delegates you have ever saw/written?
Bonus if it has went into production too!
回答1:
The LINQ Raytracer certainly tops my list =)
I'm not quite sure if qualifies as elegant but it is most certainly the coolest linq-expression I've ever seen!
Oh, and just to be extremely clear; I did not write it (Luke Hoban did)
回答2:
Some basic functionals:
public static class Functionals
{
// One-argument Y-Combinator.
public static Func<T, TResult> Y<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> F)
{
return t => F(Y(F))(t);
}
// Two-argument Y-Combinator.
public static Func<T1, T2, TResult> Y<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> F)
{
return (t1, t2) => F(Y(F))(t1, t2);
}
// Three-arugument Y-Combinator.
public static Func<T1, T2, T3, TResult> Y<T1, T2, T3, TResult>(Func<Func<T1, T2, T3, TResult>, Func<T1, T2, T3, TResult>> F)
{
return (t1, t2, t3) => F(Y(F))(t1, t2, t3);
}
// Four-arugument Y-Combinator.
public static Func<T1, T2, T3, T4, TResult> Y<T1, T2, T3, T4, TResult>(Func<Func<T1, T2, T3, T4, TResult>, Func<T1, T2, T3, T4, TResult>> F)
{
return (t1, t2, t3, t4) => F(Y(F))(t1, t2, t3, t4);
}
// Curry first argument
public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> F)
{
return t1 => t2 => F(t1, t2);
}
// Curry second argument.
public static Func<T2, Func<T1, TResult>> Curry2nd<T1, T2, TResult>(Func<T1, T2, TResult> F)
{
return t2 => t1 => F(t1, t2);
}
// Uncurry first argument.
public static Func<T1, T2, TResult> Uncurry<T1, T2, TResult>(Func<T1, Func<T2, TResult>> F)
{
return (t1, t2) => F(t1)(t2);
}
// Uncurry second argument.
public static Func<T1, T2, TResult> Uncurry2nd<T1, T2, TResult>(Func<T2, Func<T1, TResult>> F)
{
return (t1, t2) => F(t2)(t1);
}
}
Don't do much good if you don't know how to use them. In order to know that, you need to know what they're for:
- What is currying?
- What is a y-combinator?
回答3:
By far the most impressive Linq implementation i've ever come across is the Brahma framework.
It can be used to offload parallel calculations to the GPU using 'Linq to GPU'. You write a 'query' in linq, and then Brahma translates it into HLSL (High Level Shader Language) so DirectX can process it on the GPU.
This site will only let me paste one link so try this webcast from dotnetrocks:
http://www.dotnetrocks.com/default.aspx?showNum=466
Else google for Brahma Project, you'll get the right pages.
Extremely cool stuff.
GJ
回答4:
Progress Reporting for long running LINQ queries. In the blog post you can find an extension method WithProgressReporting() that lets you discover and report the progress of a linq query as it executes.
回答5:
http://igoro.com/archive/extended-linq-additional-operators-for-linq-to-objects/
http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/
回答6:
To me, the duality between delegates (Func<T,R>
, Action<T>
) and expressions (Expression<Func<T,R>>
Expression<Action<T>>
) is what gives rise to the most clever uses of lambdas.
For example:
public static class PropertyChangedExtensions
{
public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression)
{
if (handler != null)
{
// Retrieve lambda body
var body = propertyExpression.Body as MemberExpression;
if (body == null)
throw new ArgumentException("'propertyExpression' should be a member expression");
// Extract the right part (after "=>")
var vmExpression = body.Expression as ConstantExpression;
if (vmExpression == null)
throw new ArgumentException("'propertyExpression' body should be a constant expression");
// Create a reference to the calling object to pass it as the sender
LambdaExpression vmlambda = Expression.Lambda(vmExpression);
Delegate vmFunc = vmlambda.Compile();
object vm = vmFunc.DynamicInvoke();
// Extract the name of the property to raise a change on
string propertyName = body.Member.Name;
var e = new PropertyChangedEventArgs(propertyName);
handler(vm, e);
}
}
}
Then you can "safely" implement INotifyPropertyChanged
by calling
if (PropertyChanged != null)
PropertyChanged.Raise( () => MyProperty );
Note : I saw this on the web at first a few weeks ago, then lost the link and a score of variations have cropped up here and there since then so I'm afraid I cannot give proper attribution.
回答7:
Not my design but I've used it a few times, a typed-switch statement: http://community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch.aspx
Saved me so many if... else if... else if... else IF! statements
回答8:
Actually, I'm quite proud of this for generating Excel docments: http://www.aaron-powell.com/linq-to-xml-to-excel
回答9:
I did one (a bit crazy, but interesting) thing like that just recently:
- http://tomasp.net/blog/reactive-iv-reactivegame.aspx
回答10:
I was trying to come up with a cool way to build a navigation control for a website I was building. I wanted to use regular HTML unordered list elements (employing the standard CSS "Sucker Fish" look) with a top-navigation mouse-over effect that reveals the drop down items. I had a sql dependent cached DataSet with two tables (NavigationTopLevels & NavigationBottomLevels). Then all I had to was create two class objects (TopNav & SubNav) with the few required properties (the TopNav class had to have a generic list of bottomnav items -> List<SubNav> SubItems).
var TopNavs = from n in ds.NavigationTopLevels
select new TopNav
{
NavigateUrl = String.Format("{0}/{1}", tmpURL, n.id),
Text = n.Text,
id = n.id,
SubItems = new List<SubNav>(
from si in ds.NavigationBottomLevels
where si.parentID == n.id
select new SubNav
{
id = si.id,
level = si.NavLevel,
NavigateUrl = String.Format("{0}/{1}/{2}", tmpURL, n.id, si.id),
parentID = si.parentID,
Text = si.Text
}
)
};
List<TopNav> TopNavigation = TopNavs.ToList();
It might not be the "coolest" but for a lot of people who want to have dynamic navigation, its sweet not to have to muddle around in the usual looping logic that comes with that. LINQ is, if anything a time saver in this case.
回答11:
I think that LINQ is a major change to .NET and it is a very powerful tool.
I use LINQ to XML in production to parse and filter records from a 6MB XML file (with 20+ node levels) into a dataset in two lines of code.
Before LINQ this would have taken hundreds of lines of code and days to debug.
That's what I call elegant!
回答12:
Perhaps not the coolest, but recently I have been using them anytime I have a block of code that gets C+Pd over and over again only to have a few lines change. For instance, running simple SQL commands to retrieve data can be done like so:
SqlDevice device = GetDevice();
return device.GetMultiple<Post>(
"GetPosts",
(s) => {
s.Parameters.AddWithValue("@CreatedOn", DateTime.Today);
return true;
},
(r, p) => {
p.Title = r.Get<string>("Title");
// Fill out post object
return true;
}
);
Which could return a list of Posts that were created today. This way I don't have to copy and paste the try-catch-finally block fifteen million times for each command, object, et cetera.
回答13:
Working with attributes:
private void WriteMemberDescriptions(Type type)
{
var descriptions =
from member in type.GetMembers()
let attributes = member.GetAttributes<DescriptionAttribute>(true)
let attribute = attributes.FirstOrDefault()
where attribute != null
select new
{
Member = member.Name,
Text = attribute.Description
};
foreach(var description in descriptions)
{
Console.WriteLine("{0}: {1}", description.Member, description.Text);
}
}
The GetAttributes
extension method:
public static class AttributeSelection
{
public static IEnumerable<T> GetAttributes<T>(this ICustomAttributeProvider provider, bool inherit) where T : Attribute
{
if(provider == null)
{
throw new ArgumentNullException("provider");
}
return provider.GetCustomAttributes(typeof(T), inherit).Cast<T>();
}
}
AttributeSelection
is production code and also defines GetAttribute
and HasAttribute
. I chose to use the let
and where
clauses in this example.
回答14:
OLINQ reactive LINQ queries over INotifyingCollection - these allow you to do (amongst other things) realtime aggregation against large datasets.
https://github.com/wasabii/OLinq