StringHelper类是最大的辅助类之一,估计它是我曾写的第一个辅助类,因为处理字符串会卷入如此之多的问题,很容易就可以想到许多方式来改善性能,更容易地处理字符串列表,输出字符串数据等等。
如果看一看StringHelper类(如图3-9所示),您会立刻发现许多方法,并且所有重载的方法支持很多不同的参数类型。它还包含相当多的单元测试;几分钟前,您就看见过一个来自于StringHelper类的单元测试。
您可能自言自语,为什么这个类中的单元测试那么少,而方法却如此之多。这是因为很多年前我就开始写这个类了,远在我开始使用单元测试之前。其中有些方法在.Net 2.0 中没有太大的意义了,因为现在Framework实现了它们,不过我还是习惯于自己的方法。我只是希望你能在这个类中找到某些有用的方法。可能要花一些时间来习惯这么多方法,不过当您需要进行一项复杂的字符串操作时,您将会因为这个有用的方法感谢我(如果您有自己的辅助类,就是您自己)。
在System.IO命名空间的Path类中,也包含许多诸如GetDirectory、CutExtension等等的方法,不过在StringHelper类中用来处理文件名的最有用的方法之一就是ExtractFilename方法,它把路径和扩展名都去掉了,只得到文件名,再无其他。
Path.GetFileNameWithoutExtension方法做类似的一件事,不过出于某些原因我更喜欢自己的方法。如果您想实现自己的方法,并且需要一些能着手工作的代码,也可能很有趣。再强调一次:您不是必须写自己的Path方法,不过有时您不知道Framwork提供了这些,或者您只是想自己去研究一下。
自从我测试这些方法的性能以来已经过了很久,不过我还是认为大多数StringHelper类的方法比某些Path类的方法更快。
/// <summary> /// Extracts filename from full path+filename, cuts of extension /// if cutExtension is true. Can be also used to cut of directories /// from a path (only last one will remain). /// </summary> static public string ExtractFilename(string pathFile, bool cutExtension) { if (pathFile == null) return ""; // Support windows and unix slashes string[] fileName = pathFile.Split(new char[] { '\\', '/' }); if (fileName.Length == 0) { if (cutExtension) return CutExtension(pathFile); return pathFile; } // if (fileName.Length) if (cutExtension) return CutExtension(fileName[fileName.Length - 1]); return fileName[fileName.Length - 1]; } // ExtractFilename(pathFile, cutExtension)
Writing a unit test for a method like this is also very simple. Just check if the expected result is returned:
Assert.AreEqual("SomeFile", StringHelper.ExtractFilename("SomeDir\\SomeFile.bmp"));
在StringHelper类中另一个比较独特的是WriteArrayData方法,它把任何类型的列表、数组或者IEnumerable数据书写为文本字符串,这些字符串可以被写入日志文件中。实现还是非常简单:
/// <summary> /// Returns a string with the array data, ArrayList version. /// </summary> static public string WriteArrayData(ArrayList array) { StringBuilder ret = new StringBuilder(); if (array != null) foreach (object obj in array) ret.Append((ret.Length == 0 ? "" : ", ") + obj.ToString()); return ret.ToString(); } // WriteArrayData(array)
列表,甚至泛型列表都是从ArrayList类继承来的,所以能够给这个方法传递任何动态列表。对于存在特殊重载版本的Array数组、特殊的集合、byte和integer数组,这些以IEnumerable接口工作的类型也都存在对应的重载版本,不过使用非object类型的重载速度会更快。
可以编写下列代码来测试WriteArrayData方法:
/// <summary> /// Test WriteArrayData /// </summary> [Test] public void TestWriteArrayData() { Assert.AreEqual("3, 5, 10", WriteArrayData(new int[] { 3, 5, 10 })); Assert.AreEqual("one, after, another", WriteArrayData(new string[] { "one", "after", "another" })); List<string> genericList = new List<string>(); genericList.Add("whats"); genericList.AddRange(new string[] { "going", "on" }); Assert.AreEqual("whats, going, on", WriteArrayData(genericList)); } // TestWriteArray()