看到一篇关于 C# 中隐藏功能的帖子,但没有很多人写过 linq/lambdas 示例,所以......我想知道......
你见过/写过的 C# LINQ 和/或 Lambdas/匿名委托的最酷(最优雅的)用法是什么?
如果它也已投入生产,将获得奖励!
看到一篇关于 C# 中隐藏功能的帖子,但没有很多人写过 linq/lambdas 示例,所以......我想知道......
你见过/写过的 C# LINQ 和/或 Lambdas/匿名委托的最酷(最优雅的)用法是什么?
如果它也已投入生产,将获得奖励!
一些基本功能:
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);
}
}
如果您不知道如何使用它们,那就不要做太多好事。为了知道这一点,您需要知道它们的用途:
到目前为止,我遇到过的最令人印象深刻的 Linq 实现是 Brahma 框架。
它可用于使用“Linq to GPU”将并行计算卸载到 GPU。您在 linq 中编写“查询”,然后 Brahma 将其转换为 HLSL(高级着色器语言),以便 DirectX 可以在 GPU 上处理它。
这个网站只允许我粘贴一个链接,所以试试这个来自 dotnetrocks 的网络广播:
http://www.dotnetrocks.com/default.aspx?showNum=466
其他谷歌搜索 Brahma Project,你会得到正确的页面。
非常酷的东西。
GJ
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.
对我来说,委托 ( Func<T,R>
, Action<T>
) 和表达式 ( Expression<Func<T,R>>
Expression<Action<T>>
) 之间的对偶性导致了 lambda 最聪明的用法。
例如:
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);
}
}
}
然后你可以INotifyPropertyChanged
通过调用“安全地”实现
if (PropertyChanged != null)
PropertyChanged.Raise( () => MyProperty );
注意:几周前我最初在网上看到了这个,然后失去了链接,从那时起这里和那里出现了许多变体,所以我担心我无法给出正确的归属。
实际上,我为生成 Excel 文档感到非常自豪:http ://www.aaron-powell.com/linq-to-xml-to-excel
我最近做了一件(有点疯狂,但很有趣)的事情:
不是我的设计,但我已经用过几次了,一个 typed-switch 语句:http: //community.bartdesmet.net/blogs/bart/archive/2008/03/30/a-functional-c-type-switch .aspx
如果... else if... else if... else if 救了我这么多!陈述
我试图想出一种很酷的方法来为我正在构建的网站构建导航控件。我想使用常规的 HTML 无序列表元素(使用标准的CSS“Sucker Fish”外观)和顶部导航鼠标悬停效果,显示下拉项目。我有一个带有两个表(NavigationTopLevels 和 NavigationBottomLevels)的 sql 依赖缓存数据集。然后我所要做的就是创建两个类对象(TopNav 和 SubNav),它们具有几个必需的属性(TopNav 类必须有一个底部导航项的通用列表 -> List<SubNav> SubItems)。
var TopNavs = 来自 ds.NavigationTopLevels 中的 n 选择新的 TopNav { NavigateUrl = String.Format("{0}/{1}", tmpURL, n.id), 文本 = n.文本, id = n.id, 子项 = 新列表<子导航>( 来自 ds.NavigationBottomLevels 中的 si 其中 si.parentID == n.id 选择新的子导航 { id = si.id, 级别 = si.NavLevel, NavigateUrl = String.Format("{0}/{1}/{2}", tmpURL, n.id, si.id), parentID = si.parentID, 文本 = si.Text } ) }; 列表<TopNav> TopNavigation = TopNavs.ToList();
它可能不是“最酷的”,但对于许多想要动态导航的人来说,不必在随之而来的通常循环逻辑中混日子是很甜蜜的。在这种情况下,LINQ 可以节省时间。
我认为 LINQ 是对 .NET 的重大改变,它是一个非常强大的工具。
我在生产中使用 LINQ to XML 以两行代码将 6MB XML 文件(具有 20 多个节点级别)中的记录解析和过滤到数据集中。
在 LINQ 之前,这将需要数百行代码和数天的时间来调试。
这就是我所说的优雅!
也许不是最酷的,但最近我一直在使用它们,只要我有一段代码一遍又一遍地获取 C+Pd 只是改变了几行。例如,运行简单的 SQL 命令来检索数据可以这样完成:
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;
}
);
这可以返回今天创建的帖子列表。这样,我不必为每个命令、对象等复制和粘贴 try-catch-finally 块一千五百万次。
使用属性:
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);
}
}
GetAttributes
扩展方法:
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
是生产代码,还定义GetAttribute
和HasAttribute
。在本例中,我选择使用let
andwhere
子句。
OLINQ 对 INotifyingCollection 的反应式 LINQ 查询 - 这些允许您(除其他外)对大型数据集进行实时聚合。