1.自定义的泛型集合类TravelList.cs,可以根据需要筛选方法
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Collections; using System.Reflection; using System.ComponentModel; namespace CustomList { [Serializable] public class TravelList<T> : IEnumerable<T> { private List<T> innerList; //内部所使用的List,集合成员保存在这里. /// <summary> /// 集合描述,用于存储一些附带信息。 /// 类ChangedPropertyReflector中用到。 /// </summary> public string Description { get { return _description; } set { _description = value; } } private string _description = ""; /// <summary> /// 集合中元素的临时顺序号属性名,用CodeRobot代码生成器生成的业务实体才有这个属性. /// 但是不是用用CodeRobot代码生成器生成的业务实体也可以使用这个集合。 /// </summary> public string SequenceNoPropertyName { get { return _sequenceNoPropertyName; } } private string _sequenceNoPropertyName = "TmpSequenceNo"; public int TmpSequenceNo { get { return _tmpSequenceNo; } protected set { _tmpSequenceNo = value; } } private int _tmpSequenceNo = 0; private string _propertyName; private bool _isAscending; //是否升序排序 /// <summary> /// 排序时使用的一个临时类 /// </summary> private class SortPosition { public string propValue; //某个属性值 public int start; //某个属性值开始位置 public int end; //某个属性值结束位置 public int count; //某个属性值出现的个数 } private ArrayList sortArray; //排序时使用的一个临时数组,成员SortPosition //构造函数 public GenericList() { innerList = new List<T>(); } #region SortBy /// <summary> /// 把集合成员按照两个属性(字段)的值排序,属性名区分大小写 /// </summary> /// <param name="propertyName">属性名称,区分大小写</param> /// <param name="ascending">true表示按升序排序</param> public void SortBy(string propertyName, bool ascending) { if (propertyName == "") { return; } if (_propertyName == propertyName && _isAscending == ascending) _isAscending = !ascending; else { _propertyName = propertyName; _isAscending = ascending; } PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); PropertyDescriptor propertyDesc = properties.Find(propertyName, true); if (propertyDesc == null) { throw new Exception("SortBy: Not found property:" + propertyName); } // 应用排序 PropertyComparer<T> pc; pc = new PropertyComparer<T>(propertyDesc, (_isAscending) ? ListSortDirection.Ascending : ListSortDirection.Descending); innerList.Sort(pc); } /// <summary> /// 把集合成员按照两个属性(字段)的值排序,属性名区分大小写 /// </summary> /// <param name="propertyName1"></param> /// <param name="propertyName2"></param> /// <param name="ascending1">true表示按升序排序</param> ///<param name="ascending2">true表示按升序排序</param> public void SortBy(string propertyName1, bool ascending1, string propertyName2, bool ascending2) { if (propertyName1 == "") { return; } PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); PropertyDescriptor propertyDesc = properties.Find(propertyName1, true); if (propertyDesc == null) { throw new Exception("SortBy: Not found property:" + propertyName1); } // 应用排序 PropertyComparer<T> pc; pc = new PropertyComparer<T>(propertyDesc, (ascending1) ? ListSortDirection.Ascending : ListSortDirection.Descending); innerList.Sort(pc); //第一轮按照第一个属性排序 //开始第二个属性排序的计算 int index = 0; string propVal = "", prevPropVal = ""; //前一个不同的属性值 SortPosition sp; sortArray = new ArrayList(); foreach (T obj in innerList) { propVal = (PropertyComparer<T>.GetPropertyValue(obj, propertyName1)).ToString(); if (index == 0) { sp = new SortPosition(); sp.propValue = propVal; sp.start = index; sortArray.Add(sp); prevPropVal = propVal; } else { if (propVal != prevPropVal) { //如果有新值出现,则计算前一各值的数量,并将新值所代表的位置加入到sortArray里去. ((SortPosition)sortArray[sortArray.Count - 1]).end = index; ((SortPosition)sortArray[sortArray.Count - 1]).count = index - ((SortPosition)sortArray[sortArray.Count - 1]).start; sp = new SortPosition(); sp.propValue = propVal; sp.start = index; sortArray.Add(sp); prevPropVal = propVal; } } if (index == innerList.Count - 1) { //最后一个 ((SortPosition)sortArray[index - 1]).end = index; //最后一个值的数量. sortArray.Count - 2 :sortArray的倒数第二个元素 if (propVal != prevPropVal) { ((SortPosition)sortArray[sortArray.Count - 1]).count = index - ((SortPosition)sortArray[sortArray.Count - 2]).end; } else { ((SortPosition)sortArray[sortArray.Count - 1]).count = index - ((SortPosition)sortArray[sortArray.Count - 2]).end + 1; } } index += 1; } //第二轮根据第一各属性的每一个不同值,按第二个属性排序 if (propertyName2 == "") { return; } else { foreach (SortPosition pos in sortArray) { propertyDesc = properties.Find(propertyName2, true); pc = new PropertyComparer<T>(propertyDesc, (ascending2) ? ListSortDirection.Ascending : ListSortDirection.Descending); innerList.Sort(pos.start, pos.count, pc); } } } #endregion #region FindBy /// <summary> /// 按某个属性(字段)的值在集合中查找对象,找到则返回满足条件的第一个对象,找不到返回对象的默认值。 /// 属性名是区分大小写的, 对象值转换成字符串比较。 /// </summary> /// <param name="propertyName"></param> /// <param name="propertyValue"></param> /// <param name="IgnoreCase">属性值是否忽略大小写</param> /// <returns></returns> public T FindBy(string propertyName, object propertyValue, bool ignoreCase) { T foundObj = default(T); string stringValue; string tmpVal; stringValue = propertyValue.ToString(); foreach (T obj in innerList) { tmpVal = PropertyComparer<T>.GetPropertyValue(obj, propertyName).ToString(); if (String.Compare(tmpVal, stringValue, ignoreCase) == 0) { foundObj = obj; break; } } return foundObj; } /// </summary> /// 按两个属性(字段)的值在集合中查找对象,找到则返回满足条件的第一个对象,找不到返回对象的默认值。 /// 属性名是区分大小写的, 对象值转换成字符串比较。 /// </summary> /// <param name="propertyName1"></param> /// <param name="propertyValue1"></param> /// <param name="propertyName2"></param> /// <param name="propertyValue2"></param> /// <param name="ignoreCase">屬性值是否忽略大小写</param> /// <returns></returns> public T FindBy(string propertyName1, object propertyValue1, string propertyName2, object propertyValue2, bool ignoreCase) { T foundObj = default(T); string stringValue1, stringValue2; stringValue1 = propertyValue1.ToString(); stringValue2 = propertyValue2.ToString(); foreach (T obj in innerList) { if (String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName1).ToString(), stringValue1, ignoreCase) == 0 && String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName2).ToString(), stringValue2, ignoreCase) == 0) { foundObj = obj; break; } } return foundObj; } /// </summary> /// 按三个属性(字段)的值在集合中查找对象,找到则返回满足条件的第一个对象,找不到返回对象的默认值。 /// 属性名是区分大小写的, 对象值转换成字符串比较。 /// </summary> public T FindBy(string propertyName1, object propertyValue1, string propertyName2, object propertyValue2, string propertyName3, object propertyValue3, bool ignoreCase) { T foundObj = default(T); string stringValue1, stringValue2, stringValue3; stringValue1 = propertyValue1.ToString(); stringValue2 = propertyValue2.ToString(); stringValue3 = propertyValue3.ToString(); foreach (T obj in innerList) { if (String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName1).ToString(), stringValue1, ignoreCase) == 0 && String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName2).ToString(), stringValue2, ignoreCase) == 0 && String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName3).ToString(), stringValue3, ignoreCase) == 0) { foundObj = obj; break; } } return foundObj; } #endregion /// <summary> /// 返回某个属性等于某个值的子集合。 /// 属性名是区分大小写的, 对象值转换成字符串比较。 /// </summary> /// <param name="propertyName"></param> /// <param name="propertyValue"></param> /// <param name="byReference">是否生成一个新的子集合,如果是true, 則子集合里的元素不再是大集合里的元素,而是一个新生成的对象</param> /// <param name="ignoreCase">属性值是否忽略大小写</param> /// <returns></returns> public GenericList<T> GetSubList(string propertyName, object propertyValue, bool ignoreCase) { GenericList<T> subColletion = new GenericList<T>(); string stringValue; stringValue = propertyValue.ToString(); //轉爲小寫比較 foreach (T obj in innerList) { if (String.Compare(PropertyComparer<T>.GetPropertyValue(obj, propertyName).ToString(), stringValue, ignoreCase) == 0) { subColletion.Add(obj); } } return subColletion; } /// <summary> /// 添加元素,并给集合成员的临时顺序号属性赋值. /// </summary> public void Add(T obj) { //对于用代码生成器生成的对象,才有这个属性:_sequenceNoPropertyName PropertyInfo pi = obj.GetType().GetProperty(SequenceNoPropertyName); if (pi != null) { //有该属性則赋值再添加,否则直接添加. pi.SetValue(obj, TmpSequenceNo, null); TmpSequenceNo += 1; } innerList.Add(obj); } /// <summary> /// 添加元素,并给集合成员的临时顺序号属性赋值. /// </summary> public void AddRange(IEnumerable<T> collection) { foreach (T obj in collection) { PropertyInfo pi = obj.GetType().GetProperty(SequenceNoPropertyName); if (pi != null) { pi.SetValue(obj, TmpSequenceNo, null); TmpSequenceNo += 1; } innerList.Add(obj); } } /// <summary> /// 添加元素,并给集合成员的临时顺序号属性赋值. /// </summary> public void AddRange(T[] objectArray) { foreach (T obj in objectArray) { PropertyInfo pi = obj.GetType().GetProperty(SequenceNoPropertyName); if (pi != null) { pi.SetValue(obj, TmpSequenceNo, null); TmpSequenceNo += 1; } innerList.Add(obj); } } public void Insert(int index, T obj) { PropertyInfo pi = obj.GetType().GetProperty(SequenceNoPropertyName); if (pi != null) { pi.SetValue(obj, TmpSequenceNo, null); TmpSequenceNo += 1; } innerList.Insert(index, obj); } public void InsertRange(int index, IEnumerable<T> collection) { int localIndex = index; foreach (T obj in collection) { PropertyInfo pi = obj.GetType().GetProperty(SequenceNoPropertyName); if (pi != null) { pi.SetValue(obj, TmpSequenceNo, null); TmpSequenceNo += 1; } innerList.Insert(localIndex, obj); localIndex += 1; } } #region 下面实现集合一些常用的属性和方法,一些不常用的方法没有实现,需要时可以自己添加。 public int Capacity { get { return innerList.Capacity; } set { innerList.Capacity = value; } } public int Count { get { return innerList.Count; } } /// <summary>索引器</summary> public T this[int index] { get { return ((T)(innerList[index])); } } public void Clear() { innerList.Clear(); } public bool Contains(T obj) { return innerList.Contains(obj); } public int IndexOf(T obj) { return innerList.IndexOf(obj); } public int LastIndexOf(T obj) { return innerList.LastIndexOf(obj); } public void CopyTo(T[] array) { innerList.CopyTo(array); } public void CopyTo(T[] array, int arrayIndex) { innerList.CopyTo(array, arrayIndex); } public void CopyTo(int index, T[] array, int arrayIndex, int count) { innerList.CopyTo(index, array, arrayIndex, count); } /// <summary> /// 拷贝到对象数组 /// </summary> /// <returns></returns> public T[] CopyToArray() { T[] objArray = new T[innerList.Count]; innerList.CopyTo(objArray); return objArray; } public bool Remove(T obj) { return innerList.Remove(obj); } public void RemoveAt(int index) { innerList.RemoveAt(index); } /// <summary>List的Find方法</summary> public T Find(Predicate<T> match) { return innerList.Find(match); } public List<T> FindAll(Predicate<T> match) { return innerList.FindAll(match); } public void Sort() { innerList.Sort(); } public void Sort(IComparer<T> comparer) { innerList.Sort(comparer); } #endregion #region 实现IEnumerable<T>的成员,绑定GridView所必须 public IEnumerator<T> GetEnumerator() { int count = innerList.Count; for (int i = 0; i < count; i++) { yield return innerList[i]; } } //实现IEnumerable(非泛型)的成员,因为IEnumerable<T>继承自非泛型IEnumerable. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion } }
2.定义的实体类Travel.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CustomListTest { public class Travel { public Travel(string flight,DateTime flyTime,double price,int seatCount) { Flight = flight; FlyTime = flyTime; Price = price; SeatCount = seatCount; } /// <summary> /// 航班 /// </summary> public string Flight { get; set; } /// <summary> /// 起飞时间 /// </summary> public DateTime FlyTime { get; set; } /// <summary> /// 价格 /// </summary> public double Price { get; set; } /// <summary> /// 座位剩余量 /// </summary> public int SeatCount { get; set; } } }
3.自定义的一个属性比较的类PropertyComparer.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Reflection; namespace CustomListTest { /// <summary> /// 属性比较类 /// </summary> public class PropertyComparer<T> : System.Collections.Generic.IComparer<T> { private PropertyDescriptor _property; private ListSortDirection _direction; public PropertyComparer(PropertyDescriptor property, ListSortDirection direction) { _property = property; _direction = direction; } #region IComparer<T> public int Compare(T xWord, T yWord) { // 获取属性 object xValue = GetPropertyValue(xWord, _property.Name); object yValue = GetPropertyValue(yWord, _property.Name); // 调用升序或降序方法 if (_direction == ListSortDirection.Ascending) { return CompareAscending(xValue, yValue); } else { return CompareDescending(xValue, yValue); } } public bool Equals(T xWord, T yWord) { return xWord.Equals(yWord); } public int GetHashCode(T obj) { return obj.GetHashCode(); } #endregion /// <summary> /// 比较任意类型属性升序 /// </summary> /// <param name="xValue">X值</param> /// <param name="yValue">Y值</param> /// <returns></returns> private int CompareAscending(object xValue, object yValue) { int result; // 如果值实现了IComparer接口 if (xValue is IComparable) { result = ((IComparable)xValue).CompareTo(yValue); } // 如果值没有实现IComparer接口,但是它们是相等的 else if (xValue.Equals(yValue)) { result = 0; } // 值没有实现IComparer接口且它们是不相等的, 按照字符串进行比较 else result = xValue.ToString().CompareTo(yValue.ToString()); return result; } /// <summary> /// 比较任意类型属性降序 /// </summary> /// <param name="xValue">X值</param> /// <param name="yValue">Y值</param> /// <returns></returns> private int CompareDescending(object xValue, object yValue) { return CompareAscending(xValue, yValue) * -1; } /// <summary> /// 获取属性值 /// </summary> /// <param name="value">对象</param> /// <param name="property">属性</param> /// <returns></returns> public static object GetPropertyValue(T value, string property) { // 获取属性 PropertyInfo propertyInfo = value.GetType().GetProperty(property); // 返回值 return propertyInfo.GetValue(value, null); } } }
4.后台调用的简单方法Program.cs,这里只演示了按照属性一的升序和属性二的降序排列
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CustomListTest { class Program { static void Main(string[] args) { Travel travel1 = new Travel("1001",DateTime.Now.AddDays(1),151,24); Travel travel2 = new Travel("1002", DateTime.Now.AddDays(4), 152, 45); Travel travel3 = new Travel("1003", DateTime.Now.AddDays(3), 153, 12); Travel travel4 = new Travel("1004", DateTime.Now.AddDays(7), 154, 5); Travel travel5 = new Travel("1005", DateTime.Now.AddDays(5), 155, 32); Travel travel6= new Travel("1006", DateTime.Now.AddDays(4), 156, 32); Travel travel7 = new Travel("1007", DateTime.Now.AddDays(5), 151, 32); Travel travel8 = new Travel("1008", DateTime.Now.AddDays(4), 156, 32); Travel travel9= new Travel("1009", DateTime.Now.AddDays(7), 151, 32); Travel travel10 = new Travel("1010", DateTime.Now.AddDays(7), 152, 32); TravelList<Travel> list = new TravelList<Travel>(); list.Add(travel1); list.Add(travel2); list.Add(travel3); list.Add(travel4); list.Add(travel5); list.Add(travel6); list.Add(travel7); list.Add(travel8); list.Add(travel9); list.Add(travel10); list.Sort("FlyTime", true, "Price", false); foreach (var item in list) { Console.WriteLine(item.Flight + " " + item.FlyTime + " " + item.Price + " " + item.SeatCount); } Console.Read(); } } }
相关推荐
本话题主要探讨如何自定义泛型集合,并实现其中元素的交换功能。 首先,让我们从创建一个泛型集合类开始。这个类将继承自`System.Collections.Generic.List<T>`,因为它提供了基本的集合操作,并且是泛型的,因此...
除了使用内置的泛型集合类之外,还可以自定义泛型类。例如: ```csharp public class ItemList { private List<T> items = new List(); public void Add(T item) { items.Add(item); } public T Get(int ...
【C# 泛型集合详解】 C# 泛型集合是面向对象编程(OOP)中的一个重要特性,尤其是在C#语言中,它极大地提升了代码的效率和安全性。在C# 2.0版本引入泛型之后,开发人员可以更加方便地创建和管理强类型的数据集合,...
"实例185 - 自定义泛型化数组类"是一个关于如何创建和使用自定义泛型数组类的示例,这个主题将深入探讨泛型、数组以及两者的结合。 首先,我们需要理解泛型的基本概念。泛型是Java 5引入的一个重要特性,它允许我们...
在实际应用中,我们还可以自定义泛型类和方法,进一步扩展泛型的功能。例如,我们可以创建一个泛型堆栈类Stack,支持Push和Pop操作,并确保元素类型的安全性。 总之,C#中的泛型集合是实现高效、类型安全代码的关键...
Java 泛型集合和Java集合框架是Java编程中不可或缺的部分,它们为开发者提供了高效的数据存储和操作机制。本文将深入探讨这两个主题,并着重讲解`Collection`接口及其在Java中的应用。 首先,Java泛型是一种在编译...
C#泛型集合是.NET框架中一个非常重要的概念,它为开发者提供了强大的数据处理能力,同时保持了代码的高效性和类型安全。在C#中,泛型集合允许我们在不指定具体数据类型的情况下定义和操作数据结构,这极大地提高了...
泛型集合在编程中扮演着至关重要的角色,尤其是在.NET框架中,它们提供了强类型的数据存储方式,提高了代码的可读性、安全性和效率。本文将深入探讨“泛型集合应用——Dictionary, Obj>”这一主题,揭示其在实际开发...
在C#编程语言中,自定义泛型类是一种强大的工具,它允许我们创建可以处理多种数据类型的类。泛型提供了一种方式,让我们能够在编写代码时推迟对具体数据类型的决定,直到实例化类或者调用方法时。这提高了代码的重用...
例如,在“老师找学生”的场景中,我们可以创建一个泛型集合List来存储所有的学生信息,其中Student是我们自定义的数据类型,包含了学生的姓名、学号等信息。 数组则是另一种数据结构,用于存储同类型的元素序列。...
C#泛型与集合编程是.NET框架中非常重要的部分,它们极大地...而自定义泛型集合类则允许开发人员根据需求定制更复杂的逻辑,提升代码的灵活性和可维护性。理解并熟练运用这些概念,对于成为一名精通C#的开发者至关重要。
在`.NET3.0`到`.NET3.5`版本中,C#引入了更多的泛型特性,如匿名类型、LINQ(Language Integrated Query)等,这些都可以在自定义泛型集合中发挥作用。例如,通过使用LINQ,开发者可以轻松地对集合进行复杂的数据...
标题中的“泛型集合的简单应用”指的是使用泛型来操作和管理集合对象,如ArrayList、LinkedList等。在这里,我们将电脑类作为泛型参数,这意味着集合只能存储电脑类或其子类的对象。 首先,我们先了解一下泛型的...
通过实现这些接口,可以构建具有特定功能的自定义泛型集合类,增强代码的灵活性和可扩展性。 #### 构建高级泛型数据结构 随着对C#泛型特性的深入理解,可以着手构建更加复杂的泛型数据结构,如可反转排序的泛型...
而`List<T>`作为.NET Framework提供的泛型集合类,是存储数据的一种高效方式,特别是在处理类型不确定或者需要强类型安全的情况下。本篇将详细讲解如何利用泛型集合`List<T>`存储数据,并在`DataGridView`中显示和...
自定义泛型类时,常常需要结合上述各种约束使用,以确保泛型类在编译时能够保证类型安全,并在运行时能够提供必要的类型信息。下面给出了一个具体的实例: 首先定义了一个Animal基类,该基类是一个抽象类,它包含一...
在.NET框架中,C#语言提供了丰富的数据结构和容器,其中最常用且强大的就是List、Dictionary和HashSet等泛型集合。这些集合类是基于泛型的,能够提供类型安全的数据存储,大大增强了代码的可读性和效率。接下来,...
- 使用泛型集合可以避免`ClassCastException`,并提高代码的可读性和安全性。 7. **野指针异常** - 如果试图向泛型集合中添加不兼容类型的对象,编译器会报错。但是,如果通过反射或`Class.newInstance()`等方式...