C#-排序列表<;SomeClass>;通过使用自定义的CompareTo方法
我有以下类层次结构:C#-排序列表<;SomeClass>;通过使用自定义的CompareTo方法,c#,sorting,compareto,icomparable,C#,Sorting,Compareto,Icomparable,我有以下类层次结构: abstract class Product : IComparable { public string Name { get; set; } public decimal Price { get; set; } public string Barcode { get; set; } public int CompareTo(object obj) { int ret = -1; if (String
abstract class Product : IComparable
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Barcode { get; set; }
public int CompareTo(object obj)
{
int ret = -1;
if (String.Compare(this.GetType().Name, obj.GetType().Name,StringComparison.Ordinal) == 0)
ret = 0;
return ret;
}
}
abstract class Book : Product
{
public int PagesCount { get; set; }
}
class ProgrammingBook : Book
{
public string ProgrammingLanguage { get; set; }
}
class CulinaryBook : Book
{
public string MainIngridient { get; set; }
}
class EsotericBook : Book
{
public int MininumAge { get; set; }
}
abstract class Disc : Product
{
internal enum Content
{
Music,
Video,
Software
}
public Content DiscContent { get; set; }
}
class CdDisc : Disc
{
}
class DvdDisc : Disc
{
}
我尝试使用IComparable接口方法CompareTo对以下集合进行排序:
List<Product> products = new List<Product>
{
new DvdDisc {Name = "The lord of the rings 2",DiscContent = Disc.Content.Video,Price = 200M,Barcode = "5435443-2"},
new CdDisc {Name = "Antonio Vivaldi: best picks",Price = 700M, DiscContent = Disc.Content.Music,Barcode = "4543765-565"},
new CulinaryBook{Name = "Midterranian foods",MainIngridient = "Salmon",PagesCount = 436,Price = 350M,Barcode = "41457561-897"},
new CdDisc{Name = "Windows XP", DiscContent = Disc.Content.Software, Price = 950M, Barcode = "5433668-4"},
new EsotericBook{Name = "Russian Freemasonry 1731-2000",MininumAge = 21,PagesCount = 2100,Price = 3000M,Barcode = "6464632-876"},
new CdDisc {Name = "The best of Mussorgsky",Price = 300M, DiscContent = Disc.Content.Music,Barcode = "5435436-567"},
new ProgrammingBook{Name = "CLR via C#",PagesCount = 900, Price = 1110M,ProgrammingLanguage = "C#",Barcode = "5546533-2446"},
new DvdDisc {Name = "The lord of the rings 1",DiscContent = Disc.Content.Video,Price = 200M,Barcode = "54354423-2"},
new ProgrammingBook{Name = "ASP.NET MVC 4",PagesCount = 800,Price = 1200M,ProgrammingLanguage = "C#",Barcode = "46476573-65"},
new EsotericBook{Name = "Russian Freemasonry in it's future and past",MininumAge =19, PagesCount = 900, Price = 2342M,Barcode = "3656353-24"},
new CulinaryBook{Name = "Traditional Polish dishes",MainIngridient = "Red meat",PagesCount = 630,Price = 840,Barcode = "54634234-5"}
}; products.Sort();
列出产品=新列表
{
新DVD光盘{Name=“魔戒2”,DiscContent=Disc.Content.Video,价格=200M,条形码=“5435443-2”},
新的CD光盘{Name=“Antonio Vivaldi:最佳精选”,价格=700M,DiscContent=Disc.Content.Music,条形码=“4543765-565”},
新的CulinaryBook{Name=“Midtranian foods”,MainIngridient=“Salmon”,PageScont=436,Price=350M,Barcode=“41457561-897”},
新的CD光盘{Name=“Windows XP”,DiscContent=Disc.Content.Software,价格=950M,条形码=“5433668-4”},
新秘籍{Name=“俄罗斯共济会1731-2000”,MininumAge=21,pagescont=2100,Price=3000M,Barcode=“64632-876”},
新的CD光盘{Name=“Mussorgsky之最”,价格=300M,DiscContent=Disc.Content.Music,条形码=“5435436-567”},
新的编程手册{Name=“CLR via C#”,pagesont=900,Price=1110M,ProgrammingLanguage=“C#”,Barcode=“5546533-2446”},
新DVD光盘{Name=“魔戒1”,DiscContent=Disc.Content.Video,价格=200M,条形码=“54354423-2”},
新的编程手册{Name=“ASP.NET MVC 4”,PageScont=800,Price=1200M,ProgrammingLanguage=“C#”,Barcode=“46476573-65”},
新的深奥书籍{Name=“俄罗斯共济会在它的未来和过去”,MininumAge=19,pagesont=900,Price=2342M,Barcode=“3656353-24”},
新的烹饪书{Name=“传统波兰菜”,MainIngridient=“红肉”,pageScont=630,Price=840,Barcode=“54634234-5”}
}; products.Sort();
输出列表应如下所示:
1.1编程书籍1.2烹饪书籍
1.3深奥的书籍
2.1按内容排序的Cd光盘
2.2按内容排序的DVD光盘
我当前的CompareTo方法只完成部分工作——按名称比较类。您需要使用equals选项
rtn = Primary Sort;
if(rtn =0)
rtn =secondary Sort;
if(rtn =0)
rtn =tertiary Sort;
因为你的主要分类似乎是关于书的类型
你会的
rtn = this.GetType().Name.CompareTo(obj.GetType().Name);
if(rtn ==0)
rtn =this.Name.CompareTo(obj.Name);
return rtn;
如果您的问题是不希望对类型进行字母排序
然后添加到产品中
public abstract int SortOrder{get;}
并将其用作主要排序这是一个工作示例,将呈现完全相同的输出:
1.1 Programming books
1.2 Culinary books
1.3 Esoteric books
2.1 Cd discs sorted by content
2.2 DVD discs sorted by content
我还添加了I可比性,使其更容易与其他产品进行比较
abstract class Product : IComparable<Product>
{
public string Name { get; set; }
public decimal Price { get; set; }
public string Barcode { get; set; }
protected abstract int InternalSortOrder { get; }
protected virtual string SortBy { get {return Name;} }
public int CompareTo(Product obj)
{
var sameType = string.Compare(GetType().Name, obj.GetType().Name, StringComparison.Ordinal) == 0;
var sameBaseType = GetType().BaseType != null && obj.GetType().BaseType != null &&
string.Compare(GetType().BaseType.ToString(), obj.GetType().BaseType.ToString(),
StringComparison.Ordinal) == 0;
// They have the same base type, but not the same type. Order by base type first.
if (!sameType && !sameBaseType && GetType().BaseType != null && obj.GetType().BaseType != null)
{
// Order by base type first.
return string.Compare(GetType().BaseType.ToString(), obj.GetType().BaseType.ToString(),
StringComparison.Ordinal);
}
// it's the same base type (eg. book or disc)
if (sameBaseType)
{
// Order by sort order.
if (obj.InternalSortOrder != this.InternalSortOrder)
{
return InternalSortOrder.CompareTo(obj.InternalSortOrder);
}
}
if (sameType)
{
// Same sort order. We sort by name.
return string.Compare(SortBy, obj.SortBy, StringComparison.Ordinal);
}
// Order by Type.
return string.Compare(GetType().Name, obj.GetType().Name, StringComparison.Ordinal);
}
}
abstract class Book : Product
{
public int PagesCount { get; set; }
}
class ProgrammingBook : Book
{
public string ProgrammingLanguage { get; set; }
protected override int InternalSortOrder
{
get { return 1; }
}
}
class CulinaryBook : Book
{
public string MainIngridient { get; set; }
protected override int InternalSortOrder
{
get { return 2; }
}
}
class EsotericBook : Book
{
public int MininumAge { get; set; }
protected override int InternalSortOrder
{
get { return 3; }
}
}
abstract class Disc : Product
{
internal enum Content
{
Music,
Video,
Software
}
protected override string SortBy
{
get { return DiscContent.ToString(); }
}
public Content DiscContent { get; set; }
}
class CdDisc : Disc
{
protected override int InternalSortOrder
{
get { return 1; }
}
}
class DvdDisc : Disc
{
protected override int InternalSortOrder
{
get { return 2; }
}
}
抽象类产品:IComparable
{
公共字符串名称{get;set;}
公共十进制价格{get;set;}
公共字符串条形码{get;set;}
受保护的抽象int InternalSortOrder{get;}
受保护的虚拟字符串排序方式为{get{return Name;}}
公共内部比较(产品对象)
{
var sameType=string.Compare(GetType().Name,obj.GetType().Name,StringComparison.Ordinal)=0;
var sameBaseType=GetType().BaseType!=null&&obj.GetType().BaseType!=null&&
string.Compare(GetType().BaseType.ToString(),obj.GetType().BaseType.ToString(),
StringComparison.Ordinal)==0;
//它们具有相同的基类型,但不具有相同的类型。请先按基类型排序。
如果(!sameType&&!sameBaseType&&GetType().BaseType!=null&&obj.GetType().BaseType!=null)
{
//先按基本类型排序。
返回string.Compare(GetType().BaseType.ToString(),obj.GetType().BaseType.ToString(),
比较(序数);
}
//基本类型相同(如书本或光盘)
if(sameBaseType)
{
//按排序顺序。
if(obj.InternalSortOrder!=此.InternalSortOrder)
{
返回InternalSortOrder.CompareTo(对象InternalSortOrder);
}
}
if(sameType)
{
//排序顺序相同。我们按名称排序。
返回string.Compare(SortBy,obj.SortBy,StringComparison.Ordinal);
}
//按类型订购。
返回string.Compare(GetType().Name,obj.GetType().Name,StringComparison.Ordinal);
}
}
抽象类书:产品
{
公共int pageScont{get;set;}
}
课堂编程书
{
公共字符串编程语言{get;set;}
受保护的重写内部排序器
{
获取{return 1;}
}
}
烹饪类书籍:书籍
{
公共字符串维护元素{get;set;}
受保护的重写内部排序器
{
获取{return 2;}
}
}
课堂秘籍:书
{
公共int迷你图像{get;set;}
受保护的重写内部排序器
{
获取{return 3;}
}
}
抽象类:产品
{
内部枚举内容
{
音乐,
视频
软件
}
受保护的重写字符串排序
{
获取{return DiscContent.ToString();}
}
公共内容DiscContent{get;set;}
}
类别:光盘
{
受保护的重写内部排序器
{
获取{return 1;}
}
}
类别DVD光盘:光盘
{
受保护的重写内部排序器
{
获取{return 2;}
}
}
更新:
我在
产品
中添加了虚拟
排序
。默认情况下,它将转到Name
,但Disc
将返回Content
,因为您需要自定义排序,所以一个选项是向产品类添加一个附加属性并按该属性排序(例如编程书籍-SortId