本文主要介绍LINQ查询操作符
  LINQ查询为最常用的操作符定义了一个声明语法。还有许多查询操作符可用于Enumerable类。

  下面的例子需要用到LINQ基础(一)(http://www.cnblogs.com/afei-24/p/6841361.html)的一些代码

1.筛选
  LINQ查询使用where子句添加条件表达式来筛选,where子句可以合并多个表达式。

  1. var racers = from r in Formula1.GetChampions()
  2. where r.Wins> &&
  3. (r.Country == "Brazil" || r.Country =="Austria")
  4. select r;
  5.  
  6. foreach(var r in racers)
  7. {
  8. Console.WriteLine("{0:A}", r);
  9. }

  上述LINQ表达式映射为C# LINQ查询的扩展方法:
  var racers = Formula1.GetChampions().Where(r =>r.Wins>15 &&
    (r.Country == "Brazil" || r.Country =="Austria")).Select(r => r);
  注意,并不是所以查询都可以使用LINQ查询语法,也不是所有的扩展方法都映射到LINQ查询。高级查询需要使用扩展方法。

2.用索引筛选
  不能使用LINQ查询的一个例子是Where()方法的重载。在WHere()方法的重载中,可以传递第二个参数————索引。索引是筛选器返回的每个结果的计数器。可以在表达式中使用这个索引,执行基于索引的计算:

  1. var racers = Formula1.GetChampions().
  2. Where((r, index) => r.LastName.StartsWith("A") && index % != );
  3. foreach (var r in racers)
  4. {
  5. Console.WriteLine("{0:A}", r);
  6. }

3.类型筛选
  为了进行基于类型的筛选,可以使用OfType()扩展方法。

  1. object[] data = { "one", , , "four", "five", };
  2. var query = data.OfType<string>();
  3. foreach (var s in query)
  4. {
  5. Console.WriteLine(s);
  6. }

  输出:
    one
    four
    five
  从集合仅返回字符串。

4.复合的from子句
  如果需要根据对象的成员进行筛选,而该成员本身是一个系列,就可以使用复合from子句。例如,LINQ基础(一)(http://www.cnblogs.com/afei-24/p/6841361.html)中的Racer类定义了一个属性Cars,Cars是一个字符串数组。

  筛选驾驶Ferrari的所以冠军:  

  1.   var ferrariDrivers = from r in Formula1.GetChampions()
  2. from c in r.Cars
  3. where c == "Ferrari"
  4. orderby r.LastName
  5. select r.FirstName + " " + r.LastName;
  6.  
  7. foreach (var racer in ferrariDrivers)
  8. {
  9. Console.WriteLine(racer);
  10. }

  第一个from子句访问Formula1.GetChampions()方法返回的Racer对象,第二个from子句访问Racer类的Cars属性,以返回所以sting类型的赛车。

  C#编译器把复合的from子句和LINQ查询转换为SelectMany()扩展方法。SelectMany()扩展方法可以迭代序列中的序列。
  SelectMany()的重载版本:
  public static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source,
    Func<TSource, IEnumerable<TCollection>> collectionSelector,
      Func<TSource, TCollection, TResult> resultSelector);
  第一个参数是隐式参数,它从Formula1.GetChampions()方法接受Racer对象序列。第二个参数是collectionSelector委托,其中定义了内部序列,是序列的序列,本例子为Cars。第三个参数也是一个委托,为每个Racer对象的Cars属性的每个元素调用这个委托。
  这里Cars是一个字符串数组,会将每个Racer和每个字符串作为参数,调用这个委托。  

  1. var ferrariDrivers = Formula1.GetChampions().SelectMany(
  2. c => c.Cars, (r, s) => new { Racer=r,Car =s}).Where(
  3. s =>s.Car == "Ferrari").OrderBy(
  4. r => r.Racer.LastName).Select(r => r.Racer.FirstName + " " + r.Racer.LastName);
  5.  
  6. foreach (var racer in ferrariDrivers)
  7. {
  8. Console.WriteLine(racer);
  9. }

5.排序
  要对序列排序,可以使用前面使用过的orderby.也可以使用orderrby descending子句(降序)。

  1. var racers = (from r in Formula1.GetChampions()
  2. orderby r.Country descending
  3. select r);
  4.  
  5. foreach (var racer in racers)
  6. {
  7. Console.WriteLine("{0}: {1}, {2}", racer.Country, racer.LastName, racer.FirstName);
  8. }

  orderby子句解析为OrderBy()方法,orderby r.Country descending解析为OrderByDescending()方法:
  var racers = Formula1.GetChampions().OrderByDescending(r => r.Country).Select(r=>r);
  OrderBy()和OrderByDescending()方法返回IOrderEnumerable<TSource>。这个接口派生自IEnumerable<TSource>接口,但包含一个额外的方法CreateOrderEnumerable<TSource>()方法。这个方法用于进一步给序列排序,可以在最后一个参数指定升序还是降序:
  

  1. // 摘要:
  2. // 根据某个键对 System.Linq.IOrderedEnumerable<TElement> 的元素执行后续排序。
  3. //
  4. // 参数:
  5. // keySelector:
  6. // 用于提取每个元素的键的 System.Func<T,TResult>。
  7. //
  8. // comparer:
  9. // 用于比较键在返回序列中的位置的 System.Collections.Generic.IComparer<T>。
  10. //
  11. // descending:
  12. // 如果为 true,则对元素进行降序排序;如果为 false,则对元素进行升序排序。
  13. //
  14. // 类型参数:
  15. // TKey:
  16. // keySelector 生成的键的类型。
  17. //
  18. // 返回结果:
  19. // 一个 System.Linq.IOrderedEnumerable<TElement>,其元素按键排序。
  20. IOrderedEnumerable<TElement> CreateOrderedEnumerable<TKey>(Func<TElement, TKey> keySelector, IComparer<TKey> comparer, bool descending);

  例子:

  1. // Create an array of strings to sort.
  2. string[] fruits = { "apricot", "orange", "banana", "mango", "apple", "grape", "strawberry" };
  3. // First sort the strings by their length.
  4. IOrderedEnumerable<string> sortedFruits2 =
  5. fruits.OrderBy(fruit => fruit.Length);
  6. // Secondarily sort the strings alphabetically, using the default comparer.
  7. IOrderedEnumerable<string> sortedFruits3 =
  8. sortedFruits2.CreateOrderedEnumerable<string>(
  9. fruit => fruit,
  10. Comparer<string>.Default, false);

  使用ThenBy和ThenByDescending()方法进行进一步排序,可以添加任意多个:
  var racers = Formula1.GetChampions().OrderByDescending(r => r.Country).ThenByDescending(
    r => r.LastName).ThenByDescending(r => r.FirstName).Select(r => r);

6.分组
  要根据一个关键字值对查询结果分组,可以使用group子句。

  1. // group r by r.Country into g 根据Country属性组合所有的赛车手,并定义为一个新的集合g,用于访问分组的结果信息。
  2. //select子句创建一个带Country和Count属性的匿名类型。Country = g.Key Key是r.Country
  3. var countries = from r in Formula1.GetChampions()
  4. group r by r.Country into g
  5. orderby g.Count() descending, g.Key
  6. where g.Count() >=
  7. select new
  8. {
  9. Country = g.Key,
  10. Count = g.Count()
  11. };
  12. foreach (var item in countries)
  13. {
  14. Console.WriteLine("{0, -10} {1}", item.Country, item.Count);
  15. }

  输出:
  

  使用扩展方法执行相同的操作,把group r by r.Country 子句解析为GroupBy()方法。在GroupBy()方法的声明中,它返回实现了IGrouping<TKey, TSource>接口的枚举对象。IGrouping<TKey, TSource>接口定义了Key属性,所以在调用了这个方法后,可以访问分组的关键字:
  public static IEnumerable<IGrouping<TKey, TSource>> GroupBy<TSource, TKey>(this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector);
  使用GroupBy方法:

  1. var countries = Formula1.GetChampions().GroupBy(r => r.Country).OrderByDescending(
  2. g => g.Count()).ThenBy(g => g.Key).Where(g => g.Count() >= ).Select(
  3. g=>new
  4. {
  5. Country = g.Key,
  6. Count = g.Count()
  7. });

7.对嵌套的对象分组
  如果得到的分组的对象需要包含嵌套的序列,就可以改变select子句创建匿名类型。
  

  1. //返回的对象不仅需要包含国家名和赛车手这两个属性,还应包含赛车手集合。
  2. //使用from r1 in g orderby r1.LastName select r1.FirstName + " " + r1.LastName 内部子句
  3. var countries = from r in Formula1.GetChampions()
  4. group r by r.Country into g
  5. orderby g.Count() descending, g.Key
  6. where g.Count() >=
  7. select new
  8. {
  9. Country = g.Key,
  10. Count = g.Count(),
  11. Racers = from r1 in g
  12. orderby r1.LastName
  13. select r1.FirstName + " " + r1.LastName
  14. };
  15. foreach (var item in countries)
  16. {
  17. Console.WriteLine("{0, -10} {1}", item.Country, item.Count);
  18. foreach (var name in item.Racers)
  19. {
  20. Console.Write("{0}; ", name);
  21. }
  22. Console.WriteLine();
  23. }

8.内连接
  使用join子句可以根据特定的条件合并两个数据源,但之前要获得两个连接的列表。
  使用了LINQ基础(一)(http://www.cnblogs.com/afei-24/p/6841361.html)的代码  

  1. //GetChampions获得冠军赛车手
  2. var racers = from r in Formula1.GetChampions()
  3. from y in r.Years
  4. select new
  5. {
  6. Year = y,
  7. Name = r.FirstName + " " + r.LastName
  8. };
  9. //GetContructorChampions获取冠军车队
  10. var teams = from t in Formula1.GetContructorChampions()
  11. from y in t.Years
  12. select new
  13. {
  14. Year = y,
  15. Name = t.Name
  16. };
  17. //得到每一年获得冠军的赛车手和车队
  18. //通过join t in teams on r.Year equals t.Year into rt 子句连接两个数据源
  19. var racersAndTeams =
  20. (from r in racers
  21. join t in teams on r.Year equals t.Year into rt
  22. from t in rt.DefaultIfEmpty()
  23. orderby r.Year
  24. select new
  25. {
  26. Year = r.Year,
  27. Champion = r.Name,
  28. Constructor = t == null ? "no constructor championship" : t.Name
  29. });
  30.  
  31. Console.WriteLine("Year Champion\t\t Constructor Title");
  32. foreach (var item in racersAndTeams)
  33. {
  34. Console.WriteLine("{0}: {1,-20} {2}",
  35. item.Year, item.Champion, item.Constructor);
  36. }

9.左连接
  使用内连接返回匹配r.Year equals t.Year的结果。左连接返回左边数据源的全部元素,即使在右边的数据源中没有匹配的元素。
  

  1. var racers = from r in Formula1.GetChampions()
  2. from y in r.Years
  3. select new
  4. {
  5. Year = y,
  6. Name = r.FirstName + " " + r.LastName
  7. };
  8.  
  9. var teams = from t in Formula1.GetContructorChampions()
  10. from y in t.Years
  11. select new
  12. {
  13. Year = y,
  14. Name = t.Name
  15. };
  16. //左连接用join和DefaultIfEmpty方法定义。
  17. //如果查询到左侧数据源没有和右边数据源Year相同的结果,使用DefaultIfEmpty方法定义右侧的默认值(为空)
  18. var racersAndTeams =
  19. (from r in racers
  20. join t in teams on r.Year equals t.Year into rt
  21. from t in rt.DefaultIfEmpty()
  22. orderby r.Year
  23. select new
  24. {
  25. Year = r.Year,
  26. Champion = r.Name,
  27. Constructor = t == null ? "no constructor championship" : t.Name
  28. });
  29.  
  30. Console.WriteLine("Year Champion\t\t Constructor Title");
  31. foreach (var item in racersAndTeams)
  32. {
  33. Console.WriteLine("{0}: {1,-20} {2}",
  34. item.Year, item.Champion, item.Constructor);
  35. }

10.组连接
  组连接类似内连接,内连接通过某一项连接两个数据源(如 r.Year equals t.Year),组连接使用一组项连接,例如下面的例子,
  通过 new
    {
      FirstName = r.FirstName,
      LastName = r.LastName
    }
    equals
    new
    {
      FirstName = r2.FirstName,
      LastName = r2.LastName
    }
  连接两个数据源
  

  1. var racers = Formula1.GetChampionships()
  2. .SelectMany(cs => new List<RacerInfo>()
  3. {
  4. new RacerInfo {
  5. Year = cs.Year,
  6. Position = ,
  7. FirstName = cs.First.FirstName(),
  8. LastName = cs.First.LastName()
  9. },
  10. new RacerInfo {
  11. Year = cs.Year,
  12. Position = ,
  13. FirstName = cs.Second.FirstName(),
  14. LastName = cs.Second.LastName()
  15. },
  16. new RacerInfo {
  17. Year = cs.Year,
  18. Position = ,
  19. FirstName = cs.Third.FirstName(),
  20. LastName = cs.Third.LastName()
  21. }
  22. });
  23.  
  24. var q = (from r in Formula1.GetChampions()
  25. join r2 in racers on
  26. new
  27. {
  28. FirstName = r.FirstName,
  29. LastName = r.LastName
  30. }
  31. equals
  32. new
  33. {
  34. FirstName = r2.FirstName,
  35. LastName = r2.LastName
  36. }
  37. into yearResults
  38. select new
  39. {
  40. FirstName = r.FirstName,
  41. LastName = r.LastName,
  42. Wins = r.Wins,
  43. Starts = r.Starts,
  44. Results = yearResults
  45. });
  46.  
  47. foreach (var r in q)
  48. {
  49. Console.WriteLine("{0} {1}", r.FirstName, r.LastName);
  50. foreach (var results in r.Results)
  51. {
  52. Console.WriteLine("{0} {1}", results.Year, results.Position);
  53. }
  54. }

11.集合操作
  扩展方法Distinct(),Union(),Intersect()(获取交集),Except()都是集合操作。  

  1. //获取同时驾驶Ferrari和驾驶McLaren获得过冠军的赛车手
  2. static void SetOperations()
  3. {
  4. //定义一个委托,用来查询驾驶Ferrari获得过冠军的赛车手和驾驶McLaren获得过冠军的赛车手
  5. Func<string, IEnumerable<Racer>> racersByCar =
  6. car => from r in Formula1.GetChampions()
  7. from c in r.Cars
  8. where c == car
  9. orderby r.LastName
  10. select r;
  11.  
  12. Console.WriteLine("World champion with Ferrari and McLaren");
  13. //使用Intersect方法获取两个数据源的交集
  14. foreach (var racer in racersByCar("Ferrari").Intersect(racersByCar("McLaren")))
  15. {
  16. Console.WriteLine(racer);
  17. }
  18. }

12.合并
  Zip()方法是.NET 4.0新增的,允许用一个为此函数把两个相关的序列合并为一个。
  对于合并,第一个集合中的第一项与第二个集合的第一项合并,第一个集合中的第二项与第二个集合的第二项合并,以此类推。如果两个序列的项数不同,Zip()方法就会在达到较小集合的末尾时停止。

  第一个集合中的元素有一个Name属性,第二个集合中的元素有LastName和Starts属性。
  在racerNames集合上使用Zip()方法,需要把第二个集合racerNamesAndStarts作为第一个参数。第二个参数是一个委托,它通过参数first接受第一个集合的元素,通过参数second接受第二个集合的元素。其实现代码返回一个字符串:  

  1. var racerNames = from r in Formula1.GetChampions()
  2. where r.Country == "Italy"
  3. orderby r.Wins descending
  4. select new
  5. {
  6. Name = r.FirstName + " " + r.LastName
  7. };
  8.  
  9. var racerNamesAndStarts = from r in Formula1.GetChampions()
  10. where r.Country == "Italy"
  11. orderby r.Wins descending
  12. select new
  13. {
  14. LastName = r.LastName,
  15. Starts = r.Starts
  16. };
  17.  
  18. var racers = racerNames.Zip(racerNamesAndStarts, (first, second) => first.Name + ", starts: " + second.Starts);
  19. foreach (var r in racers)
  20. {
  21. Console.WriteLine(r);
  22. }

13.分区
  扩展方法Take()和Skip()等的分区操作可用于分页。
  例如,在第一页只显示5个赛车手,下一页显示接下来的5个赛车手...
  Skip(page * pageSize)方法调到指定索引出,忽略前面的数据。Take(pageSize)方法显示pageSize条数据
  

  1. int pageSize = ;
  2.  
  3. int numberPages = (int)Math.Ceiling(Formula1.GetChampions().Count() /
  4. (double)pageSize);
  5.  
  6. for (int page = ; page < numberPages; page++)
  7. {
  8. Console.WriteLine("Page {0}", page);
  9.  
  10. var racers =
  11. (from r in Formula1.GetChampions()
  12. orderby r.LastName, r.FirstName
  13. select r.FirstName + " " + r.LastName).
  14. Skip(page * pageSize).Take(pageSize);
  15.  
  16. foreach (var name in racers)
  17. {
  18. Console.WriteLine(name);
  19. }
  20. Console.WriteLine();
  21. }

  TakeWhile()和SkipWhile()方法,传递一个委托,满足这个条件的数据就提取或跳转:
  public static IEnumerable<TSource> SkipWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

14.聚合操作符
  聚合操作符(如Count(),Sum(),Min(),Max(),Average(),Aggregate())不返回一个序列,而是返回一个值。
  例如,使用Count方法应用于Racer的Years属性,筛选获得冠军次数超过3次的赛车手。因为多次使用r.Years.Count(),所以使用let子句定义了一个变量。  

  

  1. var query = from r in Formula1.GetChampions()
  2. let numberYears = r.Years.Count()
  3. where numberYears >=
  4. orderby numberYears descending, r.LastName
  5. select new
  6. {
  7. Name = r.FirstName + " " + r.LastName,
  8. TimesChampion = numberYears
  9. };
  10.  
  11. foreach (var r in query)
  12. {
  13. Console.WriteLine("{0} {1}", r.Name, r.TimesChampion);
  14. }

  Aggregate()方法传递一个委托,将数据源中的每个元素作为委托的参数,并使用指定的函数累加。

15.转换操作符
  LINQ基础(一)(http://www.cnblogs.com/afei-24/p/6841361.html)提到,查询会推迟到迭代数据项时才执行,使用转换操作符会立即执行查询,把查询结果放在数组,列表和字典中。  

    

  1. //转换为数组
  2. var names = new List<string> { "Nino", "Alberto", "Juan", "Mike", "Phil" };
  3.  
  4. var namesWithJ = (from n in names
  5. where n.StartsWith("J")
  6. orderby n
  7. select n).ToList();

  转换为Lookup<TKey,TElement>
  

  1. //把Car赛车属性作为键,每个键关联多个车手Racer
  2. var racers = (from r in Formula1.GetChampions()
  3. from c in r.Cars
  4. select new
  5. {
  6. Car = c,
  7. Racer = r
  8. }).ToLookup(cr => cr.Car, cr => cr.Racer);
  9. foreach (var v in racers)
  10. {
  11. Console.Write(v.Key+"........");
  12. foreach (var k in racers[v.Key])
  13. {
  14. Console.WriteLine(k);
  15. }
  16. }

  ToLookup(cr => cr.Car, cr => cr.Racer)方法的一个重载版本传递一个键和一个元素选择器

  如果需要在非类型化的集合上使用LINQ查询,可以使用Cast()方法,定义强类型化的查询:  

  1. var list = new System.Collections.ArrayList(Formula1.GetChampions() as System.Collections.ICollection);
  2.  
  3. var query = from r in list.Cast<Racer>()
  4. where r.Country == "USA"
  5. orderby r.Wins descending
  6. select r;
  7. foreach (var racer in query)
  8. {
  9. Console.WriteLine("{0:A}", racer);
  10. }

  Cast<Racer>()将 System.Collections.IEnumerable 的元素强制转换为指定的类型。

16.生成操作符
  生成操作符Range(),Empty(),Repeat()方法不是扩展方法,而是返回序列的正常静态方法。在LING to Object中,这些方法可用于Enumerable类。
  Range()方法用来填充一个范围的数字。第一个参数作为起始值,第二个参数作为要填充的项数:
    var values = Enumerable.Range(1,20);
  结果为1至20的集合。

  可以把该结果与其它扩展方法合并:
    var values = Enumerable.Range(1,20).Select(n=> n*3);

  Empty()方法返回一个不返回值的迭代器,它用于需要一个集合的参数,其中可以给参数传递空集合。
  Repeat()方法返回指定个数的重复值的集合迭代器。

LINQ基础(二)的更多相关文章

  1. LINQ基础(三)

    一.并行LINQ System.Linq名称空间中包含的类ParallelEnumerable可以分解查询的工作,使其分布在多个线程上. 尽管Enumerable类给IEnumerable<T& ...

  2. Linq基础操作之Select,Where,OrderBy,ThenBy源码分析

    Linq基础操作之Select,Where,OrderBy,ThenBy源码分析 二:Select 它是延迟执行.yield有得一拼,因为他们都是生成了一个枚举类. if (source is TSo ...

  3. Linq基础必备

    1.linq基础必备之对象初始化器和匿名类型因果分析   3. 一:对象初始化器 1.就是在new的时候给公共属性赋值的一种方式 2. 在没有初始化器之前的时候,我们是怎么初始化的呢??? 1. 构造 ...

  4. [LINQ2Dapper]最完整Dapper To Linq框架(二)---动态化查询

    目录 [LINQ2Dapper]最完整Dapper To Linq框架(一)---基础查询 [LINQ2Dapper]最完整Dapper To Linq框架(二)---动态化查询 [LINQ2Dapp ...

  5. Python全栈开发【基础二】

    Python全栈开发[基础二] 本节内容: Python 运算符(算术运算.比较运算.赋值运算.逻辑运算.成员运算) 基本数据类型(数字.布尔值.字符串.列表.元组.字典) 其他(编码,range,f ...

  6. Bootstrap <基础二十九>面板(Panels)

    Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...

  7. Bootstrap <基础二十八>列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  8. Bootstrap<基础二十七> 多媒体对象(Media Object)

    Bootstrap 中的多媒体对象(Media Object).这些抽象的对象样式用于创建各种类型的组件(比如:博客评论),我们可以在组件中使用图文混排,图像可以左对齐或者右对齐.媒体对象可以用更少的 ...

  9. Bootstrap <基础二十六>进度条

    Bootstrap 进度条.在本教程中,你将看到如何使用 Bootstrap 创建加载.重定向或动作状态的进度条. Bootstrap 进度条使用 CSS3 过渡和动画来获得该效果.Internet ...

随机推荐

  1. jQuery 事件——关于select选中

    场景: eg:在管理一篇博文时,因博文的管理有一列叫:状态的列,该列有诸多状态,如:正常,待审核,删除等... 此时,若使用Select下拉列表进行状态选择,并在选中具体项值后,通过Ajax异步提交, ...

  2. MyBatis原始dao开发及问题总结(五)

    一.MyBatis原始Dao开发方式 1.原始dao开发需要程序员编写dao接口和dao接口实现类 编写UserDao接口:UserDao.java package codeRose.dao; pub ...

  3. Spring:利用PerformanceMonitorInterceptor来协助应用性能优化

    前段时间对公司产品做性能优化,如果单依赖于测试,进度就会很慢.所以就通过对代码的方式来完成,并以此来加快项目进度.具体的执行方案自然就是要知道各个业务执行时间,针对业务来进行优化. 因为项目中使用了S ...

  4. 在docker container中运行docker-compose

    为了保持宿主主机的环境干净,因此将docker-compose安装到一个基于centos7.3的容器之中,因为tianchao屏蔽了amazonaws,最后选择了通过pip方式来安装,这也是官方推荐的 ...

  5. 分块编码(Transfer-Encoding: chunked)

    参考链接: HTTP 协议中的 Transfer-Encoding 分块传输编码 一.背景: 持续连接的问题:对于非持续连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界:而对于持续连接,这种 ...

  6. java 接口默认修饰符问题

    package test; public interface InterfaceTest { void todo();} /** * 以下是反编译的内容,接口里的方法默认都是public的.abstr ...

  7. unity插件开发——一个例子:简单的svn集成

    在unity开发过程中,通常我们习惯性地在Windows操作系统下使用svn进行版本管理,而每次提交更新,都需要回到文件夹下的这种操作让人无法忍受.是不是可以集成svn到unity中呢?查了一圈uni ...

  8. Linux 下安装 Memcached 和 PHP 开启 Memcached 扩展

    [项目背景]:阿里云ECS服务器,Linux(centos7.2 64位),环境部署使用的是阿里云一键安装包(LAMP)等 [项目需求]:linux安装memcached 和php开启Memcache ...

  9. Windows下检测文件名大小写是否匹配

    跨平台开发有一个众所周知,但因为只是偶尔受到困扰,一般人不会在意的问题,就是windows对文件名大小写不敏感,而其他平台对文件名大小写敏感.因此可能出现在windows平台开发时一切正常,但部署/打 ...

  10. C++中进制转换问题

    一直在刷题的时候,都会遇到一个坑,就是进制转换的问题.而每一次都傻乎乎的自己去实现一个.所以算是对以前的坑的一个总结. itoa 函数 itoa是广泛应用的非标准C语言和C++语言扩展函数.由于它不是 ...