public class DiffInfo : ArrayList { } //定义DiffInfo类型 //非静态diff方法 //public void StartDiff() //{ //} /// <summary> /// 静态diff方法 /// </summary> /// <param name="fileA"></param> /// <param name="fileB"></param> /// <returns></returns> public static DiffInfo DiffFiles(List <string> fileA, List <string> fileB) { DiffInfo diffFile = new DiffInfo(); ListStringLCS lcsObject = new ListStringLCS(fileA, fileB); //创建一个LCS类的对象 lcsObject.GetLCS(); int lineNoA, lineNoB, prevLineNoA, prevLineNoB; prevLineNoA = 0; prevLineNoB = 0; lineNoA = 0; lineNoB = 0; //将LCS中的项及冲突项依次加入diffFile中 foreach (LCSItem lcsItem in lcsObject.lcs) { int lcsIndex = lcsObject.lcs.IndexOf(lcsItem); lineNoA = lcsItem.lineOfFileA; lineNoB = lcsItem.lintOfFileB; if (lineNoA - prevLineNoA == 1 && lineNoB - prevLineNoB == 1) { } else if (lineNoA - prevLineNoA == 1 && lineNoB - prevLineNoB > 1)//增加的情况 { ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.ADD; cItem.contentA = null; cItem.contentB = new List <string>(); for (int i = prevLineNoB; i < lineNoB - 1; i++) //将fileB中增加的行加入此项 { cItem.contentB.Add(fileB[i]); } diffFile.Add(cItem); //prevLineNoA = lineNoA; //prev指针下移 //prevLineNoB = lineNoB; } else if (lineNoA - prevLineNoA > 1 && lineNoB - prevLineNoB == 1) //删除的情况 { ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.DELETE; cItem.contentA = new List <string>(); cItem.contentB = null; for (int i = prevLineNoA; i < lineNoA - 1; i++) //将fileA中删除的行加入此项 { cItem.contentA.Add(fileA[i]); } diffFile.Add(cItem); //prevLineNoA = lineNoA; //prev指针下移 //prevLineNoB = lineNoB; } //lineNoA - prevLineNoA > 1 && lineNoB - prevLineNoB > 1,同时有增加和删除 else { #region 先后顺序将两边的冲突项加入diffFile //下面分支的作用是将行号靠前的一边构造的冲突项先加入diffFile if (prevLineNoA >= prevLineNoB) { //先加入左边删除项 ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.DELETE; cItem.contentA = new List <string>(); cItem.contentB = null; for (int i = prevLineNoA; i < lineNoA - 1; i++) //将fileA中删除的行加入contentA { cItem.contentA.Add(fileA[i]); } diffFile.Add(cItem); //后加入右边增加项 cItem = new ConfictItem(); cItem.type = ConfictType.ADD; cItem.contentA = null; cItem.contentB = new List <string>(); for (int i = prevLineNoB; i < lineNoB - 1; i++) { cItem.contentB.Add(fileB[i]); } //将fileB中增加的行加入contentB diffFile.Add(cItem); } else { //先加入右边增加项 ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.ADD; cItem.contentA = null; cItem.contentB = new List <string>(); for (int i = prevLineNoB; i < lineNoB - 1; i++) { cItem.contentB.Add(fileB[i]); } diffFile.Add(cItem); //先加入左边删除项 cItem = new ConfictItem(); cItem.type = ConfictType.DELETE; cItem.contentB = null; cItem.contentA = new List <string>(); for (int i = prevLineNoA; i < lineNoA - 1; i++) { cItem.contentA.Add(fileA[i]); } diffFile.Add(cItem); } #endregion //prevLineNoA = lineNoA; //prev指针下移 //prevLineNoB = lineNoB; } #region 将LCS中的项加入diffFile if (lcsItem.isExactSame) //完全相同的项直接加入diffFile { diffFile.Add(lcsItem.lineContent.ToString()); prevLineNoA = lineNoA; //prev指针下移 prevLineNoB = lineNoB; } else//有修改的项作为冲突项加入diffFile { ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.MODIFIED; cItem.contentA = new List <string>(); cItem.contentB = new List <string>(); do//使用循环将连续的有修改的项合并到一个冲突项 { //分隔符前面的内容加入contentA,后面的内容加入contentB int indexDiv = lcsItem.lineContent.ToString().IndexOf("$DIVIDER$"); cItem.contentA.Add(lcsItem.lineContent.ToString().Substring(0, indexDiv)); cItem.contentB.Add(lcsItem.lineContent.ToString().Substring(indexDiv + 9)); diffFile.Add(cItem); //将冲突项加入diffFile prevLineNoA = lineNoA; //prev指针下移 prevLineNoB = lineNoB; } while (lineNoA - prevLineNoA == 1 && lineNoB - prevLineNoB == 1 && !lcsItem.isExactSame); } #endregion } #region 处理剩余项 if (lineNoA < fileA.Count) //如果还有删除项 { ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.DELETE; cItem.contentA = new List <string>(); cItem.contentB = null; for (int i = lineNoA; i < fileA.Count; i++) { cItem.contentA.Add(fileA[i]); } diffFile.Add(cItem); } if (lineNoB < fileB.Count) //如果还有增加项 { ConfictItem cItem = new ConfictItem(); cItem.type = ConfictType.ADD; cItem.contentA = null; cItem.contentB = new List <string>(); for (int i = lineNoB; i < fileB.Count; i++) { cItem.contentB.Add(fileB[i]); } } #endregion return(diffFile); }