你可以用不同的方式写这个

时间:2008-10-19 19:22:56

标签: c# .net

.NET 3.5 / C#3.0中有一些很酷且令人兴奋的功能,这些功能带来了一些非常有趣的方法来编写完全相同的代码行。

使用上面提到的工具集(以及扩展名为.NET 2.0的东西),下面的代码片段可以合理地重写的不同方式有哪些?

        string uploadDirectory = "c:\\some\\path\\";
        if (Directory.Exists(uploadDirectory)) {
            string[] files = Directory.GetFiles(uploadDirectory);
            foreach (string filename in files) {
                if (File.GetLastWriteTime(filename).AddHours(12) < DateTime.Now) {
                    File.Delete(filename);
                }
            }
        }

2 个答案:

答案 0 :(得分:9)

LAMBDA:

if (Directory.Exists(uploadDirectory)) 
  Directory.GetFiles(uploadDirectory)
    .Where(f => File.GetLastWriteTime(file) < DateTime.Now.AddHours(-12))
    .Each(f => File.Delete(f));

编辑:第二个想法,你可以通过使用DirectoryInfo和FileInfo而不是静态文件方法来避免每个文件访问的安全性查找:

var di = new DirectoryInfo(uploadDirectory);
if (di.Exists()) {
   di.GetFiles()
     .Where(f => f.LastWriteTime < DateTime.Now.AddHours(-12))
     .Each(f=> f.Delete());
}

对于那些缺少自己的每种方法的人:

void Each<T>(this IEnumerable e, Action<T> action) {
  foreach (T t in e) {
    action(t);
  }
}

为了让它真的变得疯狂,并且适合C#3.0主题,让我们抛出一个匿名类型:

di.GetFiles().Select(f => new() {
   Delete = f.LastWriteTime < DateTime.Now.AddHours(-12) ? f.Delete : () => { }
}).Delete();

但这没有任何意义。 ;)

答案 1 :(得分:3)

嗯,第一位非常巧妙地映射到LINQ查询...但是(有意)在常规LINQ中没有ForEach。我们可以惹恼Eric并添加一个,但是:-p

所以下面使用LINQ和自定义扩展方法 - 但我们可以重写 exact 相同的代码(即相同的IL):

  • 查询语法(如下所示)
  • 流利的语法(.Where()。选择()ec)
  • 显式静态(Enumerable.Where(...))
  • lambdas vs匿名方法vs命名方法(最后更改IL)
  • 代表有/无缩写(C#2.0)委托“新”语法
  • 带/不带泛型类型推断的泛型调用(Where()vs Where&lt; T&gt;())
  • 调用File.Delete vs调用x =&gt; File.Delete(x)等

static void Main()
{
    string uploadDirectory = "c:\\some\\path\\";
    if (Directory.Exists(uploadDirectory))
    {
        var files = from filename in Directory.GetFiles(uploadDirectory)
                  where File.GetLastWriteTime(filename) < DateTime.Now.AddHours(-12)
                  select filename;
        files.ForEach(File.Delete);            
    }
}
static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
    foreach (T item in items)
    {
        action(item);
    }
}

我们可以使用自定义DateTime编写Expression代码,但这样会有点过分......

然而,我怀疑我们可能会用尽它的写作方式;-p