一个用来计算文本大小的方法(以及再一次对闭包的解释)

闭包 与Lambda

先看一下这个方法:

 private static string FormatBytes(long bytes)
        {
            string[] magnitudes = new string[] { "GB", "MB", "KB", "Bytes" };
            long max =(long)Math.Pow(1024, magnitudes.Length);
            return string.Format("{1:##.##} {0}",
                magnitudes.FirstOrDefault(
                    magnitude =>
                        bytes > (max /= 1024)) ?? "0 Bytes",
                (decimal)bytes / (decimal)max).Trim();
        }

这个方法可以用来计算一个网页HTML内容的长度的,比如我们使用下面这样的方式:

 WebRequest webRequest =WebRequest.Create(url);
 WebResponse response =webRequest.GetResponse();
 Console.Write(".....");
 using (StreamReader reader =new StreamReader(response.GetResponseStream()))
    {
      string text =reader.ReadToEnd();
      Console.WriteLine(FormatBytes(text.Length));
    }

用这个方法可以获取网站请求的一个Response,然后从流中读取string文本的长度,然后可以用FormatBytes方法来得到该文本的长度,本文主要研究上面那个计算文本长度并转化为文件大小的方法FormatBytes():
magnitudes :该方法首先定义一个字符串数组,用于后面的计算。
max :得到该数组的1024的字符串长度数的幂,在这个例子中,就是1024的4次方。
③根据该方法的一个传入参数(该例中就是获取网页HTML文本的大小)bytes,以及max这两个变量,传入扩展方法string.FirstOrDefault中,此时,FirstOrDefault方法中的Lambda表达式形成了一个闭包:有兴趣的同学可以Reflector一下。这两个变量由于闭包的形成,在编译器生成的代码中已经被一个编译器生成的类(类似于<>c_DisplayClass1之类的东西,顺便说明一下,C#的编译器会帮助我们做很多事,比如异步Async和await生成的状态机,还有迭代器,所有这些由C#编译器生成的类,都是由<>这样的尖括号前缀表明的。)的字段所取代。也就是说,本来这两个变量的作用域在方法内部,编译器为了能够在方法的栈帧销毁后继续使用这两个变量(为了Lambda表达式,更准确的说,为了Lambda表达式的延迟执行),将这两个局部(本地)变量的级别提升为类字段的级别。
接着来说string.FirstOrDefault,string类型实现了IEnumerable接口,所以能使用IEnumerable上面的扩展方法,FirstOrDefault内接收一个Func<string,bool>的predicate(谓词),在这个方法中,该predicate为:

magnitude =>bytes > (max /= 1024)) 

由于Func<string,bool>返回的是一个string,所以该扩展方法会立即执行。该扩展方法会使用这个predicate来遍历magnitudes,每遍历一次,max都要除以1024(max /= 1024),直到返回true。当然,如果找不到这个值,会返回一个默认值,该默认值根据不同类型返回不同的默认值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值