我正在尝试编写一种可以同时接收集合和排序策略的排序方法。
我可以简单地收到一个IComparer,但我更愿意列举一些可能的排序策略。打电话的人必须从那里挑选他们的。
类似的东西:
public enum SortingStrategies { ByAgeDesc, ByAgeAsc, ByIncomeDesc, ByInconmeAsc };
其中每一个(ByAgeDesc,ByAgeAsc ......)都是IComparer。
然后调用排序方法:
myObject.SortCollection(myCollection, SortingStrategies.ByIncomeDesc);
是否可以创建实例枚举?这是个好主意吗?
提前致谢!
答案 0 :(得分:7)
我不会使用直接枚举。我创建了一堆IComparer<T>
实现来从中选择:
public static class SortingStrategy
{
public static readonly IComparer<Person> ByAgeDescending = ...;
public static readonly IComparer<Person> ByAgeAscending = ...;
public static readonly IComparer<Person> ByIncomeDescending = ...;
public static readonly IComparer<Person> ByIncomeAscending = ...;
}
...或者很可能使用组合来执行升序/降序部分(例如,通过IComparer<T>
上的扩展方法来创建可逆包装器。)
现在,这不会强制调用者使用您的预定义值之一。您可以使用自己的类强制它:
public abstract class SortingStrategy : IComparer<Person>
{
public static readonly SortingStrategy ByAgeDescending = ...;
public static readonly SortingStrategy ByAgeAscending = ...;
public static readonly SortingStrategy ByIncomeDescending = ...;
public static readonly SortingStrategy ByIncomeAscending = ...;
private SortingStrategy() {}
private class ByAgeStrategy : SortingStrategy { ... }
private class ByIncomeStrategy : SortingStrategy { ... }
}
这里私有构造函数阻止任何其他子类,但私有嵌套类仍然可以继承它,因为它们可以访问构造函数。
然后,您可以使用SortingStrategy
代替IComparer<T>
而不是{{1}}。
当然,正如詹姆斯所说,使用LINQ可能会在更长的时间内更灵活。这取决于你的目标。
答案 1 :(得分:1)
C#不允许使用任意数据类型的枚举(VB.NET类型,带有黑客)。但您可以简单地将单个排序策略声明为static readonly
类的SortingStrategies
字段,并使其实现IComparable
。
另一方面,您现在已经对分类策略进行了硬编码。在某些情况下这可能是完全可以接受的,但我会保持警惕,因为它不是可以完全扩展的。
答案 2 :(得分:1)
在这里,您将最终得到一个开关或if块,这在代码可重用性/可伸缩性方面很难看。在这里使用Strategy Pattern会好得多。
所以对于策略模式的排序示例
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Strategy.RealWorld
{
/// <summary>
/// MainApp startup class for Real-World
/// Strategy Design Pattern.
/// </summary>
class MainApp
{
/// <summary>
/// Entry point into console application.
/// </summary>
static void Main()
{
// Two contexts following different strategies
SortedList studentRecords = new SortedList();
studentRecords.Add("Samual");
studentRecords.Add("Jimmy");
studentRecords.Add("Sandra");
studentRecords.Add("Vivek");
studentRecords.Add("Anna");
studentRecords.SetSortStrategy(new QuickSort());
studentRecords.Sort();
studentRecords.SetSortStrategy(new ShellSort());
studentRecords.Sort();
studentRecords.SetSortStrategy(new MergeSort());
studentRecords.Sort();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Strategy' abstract class
/// </summary>
abstract class SortStrategy
{
public abstract void Sort(List<string> list);
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class QuickSort : SortStrategy
{
public override void Sort(List<string> list)
{
list.Sort(); // Default is Quicksort
Console.WriteLine("QuickSorted list ");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ShellSort : SortStrategy
{
public override void Sort(List<string> list)
{
//list.ShellSort(); not-implemented
Console.WriteLine("ShellSorted list ");
}
}
/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class MergeSort : SortStrategy
{
public override void Sort(List<string> list)
{
//list.MergeSort(); not-implemented
Console.WriteLine("MergeSorted list ");
}
}
/// <summary>
/// The 'Context' class
/// </summary>
class SortedList
{
private List<string> _list = new List<string>();
private SortStrategy _sortstrategy;
public void SetSortStrategy(SortStrategy sortstrategy)
{
this._sortstrategy = sortstrategy;
}
public void Add(string name)
{
_list.Add(name);
}
public void Sort()
{
_sortstrategy.Sort(_list);
// Iterate over list and display results
foreach (string name in _list)
Console.WriteLine(" " + name);
Console.WriteLine();
}
}
}
有关此模式的更多信息以及上述代码的说明,请参阅http://www.dofactory.com/Default.aspx。
我跳这有帮助。
答案 3 :(得分:0)
您可以轻松添加扩展方法(如果myObject
属于某种系统类型),例如
public static IEnumerable<MyObjectType>SortCollection(this MyObjectType myObject, SortingStrategies sotrStrategy)
{
....
}
并使用此
MyObjectType myObject = new ....
myObject.Sort(SortingStrategies.ByAgeDesc);
如果myObject
非系统类型,只需向 类型添加新功能。
答案 4 :(得分:0)
枚举值不能是IComparer
。但是,您可以创建一个静态类:
public static class SortingStrategies{
static SortingStrategies() {
ByAgeDesc = new ByAgeDescComparer();
ByAgeAsc = new ByAgeAscComparer();
ByIncomeDesc = new ByIncomeDescComparer()
}
public static IComparer ByAgeDesc { get; private set; }
public static IComparer ByAgeAsc { get; private set; }
public static IComparer ByIncomeDesc { get; private set; }
}
您可以像这样引用所需的IComparer
:
SortingStrategies.ByIncomeDesc