C#表达式,相当于ruby';s夹心分组码

C#表达式,相当于ruby';s夹心分组码,c#,ruby,block,C#,Ruby,Block,我是一名.NET开发人员,最近开始使用ruby_koans学习ruby。Ruby的一些语法令人惊讶,其中之一就是它处理“三明治”代码的方式 下面是ruby三明治代码 def file_sandwich(file_name) file = open(file_name) yield(file) ensure file.close if file end def count_lines2(file_name) file_sandwich(file_n

我是一名.NET开发人员,最近开始使用ruby_koans学习ruby。Ruby的一些语法令人惊讶,其中之一就是它处理“三明治”代码的方式

下面是ruby三明治代码

  def file_sandwich(file_name)
    file = open(file_name)
    yield(file)
  ensure
    file.close if file
  end

  def count_lines2(file_name)
    file_sandwich(file_name) do |file|
      count = 0
      while line = file.gets
        count += 1
      end
      count
    end
  end

  def test_counting_lines2
    assert_equal 4, count_lines2("example_file.txt")
  end
每次访问文件时,我都能摆脱繁琐的“文件打开和关闭代码”,但我想不出任何C#等价的代码,这让我很着迷。也许,我可以使用IoC的动态代理来做同样的事情,但是有没有什么方法可以完全用C#来做呢


非常感谢。

您当然不需要任何与国际奥委会相关的东西。那么:

public T ActOnFile<T>(string filename, Func<Stream, T> func)
{
    using (Stream stream = File.OpenRead(stream))
    {
        return func(stream);
    }
}

public int CountLines(string filename)
{
    return ActOnFile(filename, stream =>
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            int count = 0;
            while (reader.ReadLine() != null)
            {
                count++;
            }
            return count;
        }
    });
}
请注意,这仍将一次只读取一行。。。但是
Count
扩展方法作用于返回的序列

在.NET 3.5中,它将是:

public int CountLines(string filename)
{
    using (var reader = File.OpenText(filename))
    {
        int count = 0;
        while (reader.ReadLine() != null)
        {
            count++;
        }
        return count;
    }
}

。。。还是很简单。

你只是在寻找能为你打开和关闭流的东西吗

public IEnumerable<string>GetFileLines(string path)
{
    //the using() statement will open, close, and dispose your stream for you:
    using(FileStream fs = new FileStream(path, FileMode.Open))
    {
       //do stuff here
    }
}
public IEnumerablegeetFileLines(字符串路径)
{
//using()语句将为您打开、关闭和处置流:
使用(FileStream fs=newfilestream(路径,FileMode.Open))
{
//在这里做事
}
}

你在寻找什么

使用
将在到达右大括号时调用Dispose()和Close(),但我认为问题在于如何实现这种特殊的代码结构

编辑:我刚刚意识到这并不是你想要的,但我将把这个答案留在这里,因为很多人都不知道这个技术

static IEnumerable<string> GetLines(string filename)
{
    using (var r = new StreamReader(filename))
    {
        string line;
        while ((line = r.ReadLine()) != null)
            yield return line;
    }
}

static void Main(string[] args)
{
    Console.WriteLine(GetLines("file.txt").Count());

    //Or, similarly: 

    int count = 0;
    foreach (var l in GetLines("file.txt"))
        count++;
    Console.WriteLine(count);
}
静态IEnumerable GetLines(字符串文件名)
{
使用(var r=newstreamreader(文件名))
{
弦线;
而((line=r.ReadLine())!=null)
收益率回归线;
}
}
静态void Main(字符串[]参数)
{
Console.WriteLine(GetLines(“file.txt”).Count();
//或者,类似地:
整数计数=0;
foreach(GetLines中的var l(“file.txt”))
计数++;
控制台写入线(计数);
}

非常感谢。我在寻找一种C#方法来处理三明治代码,就是这样。
static IEnumerable<string> GetLines(string filename)
{
    using (var r = new StreamReader(filename))
    {
        string line;
        while ((line = r.ReadLine()) != null)
            yield return line;
    }
}

static void Main(string[] args)
{
    Console.WriteLine(GetLines("file.txt").Count());

    //Or, similarly: 

    int count = 0;
    foreach (var l in GetLines("file.txt"))
        count++;
    Console.WriteLine(count);
}