【问题标题】:Returning a Sorted List of Objects based on an Abstract Class基于抽象类返回对象的排序列表
【发布时间】:2012-08-24 04:29:44
【问题描述】:

我有一个抽象类,它定义了整个网站的社交使用对象(社交协作对象)的基本行为。

internal abstract class SCO
{
    public double HotScore { get; set; }
    public double UpVotes { get; set; }
    public double DownVotes { get; set; }
    public double VoteTotal { get; set; }
    public DateTime Created { get; set; }

    public SCO(DBItem item, List<Vote> votes )
    {
        var voteMeta = InformationForThisVote(votes, item.ID);
        UpVotes = voteMeta.UpVotes;
        DownVotes = voteMeta.DownVotes;
        VoteTotal = UpVotes - DownVotes;
        HotScore = Calculation.HotScore(Convert.ToInt32(UpVotes), Convert.ToInt32(DownVotes), Convert.ToDateTime(item["Created"]));
        Created = Convert.ToDateTime(item["Created"]);
    }

    private static VoteMeta InformationForThisVote(List<Vote> votes, int itemId)
    {
        // Loop through votes, find matches by id, 
        // and record number of upvotes and downvotes
    }
    private User GetCreatorFromItemValue(DBItem item)
    {
        // Cast User Object from property of DataBase information
    }
}

这是一个继承对象的示例:

class Post : SCO
{
    public string Summary { get; set; }
    public Uri Link { get; set; }
    public Uri ImageUrl { get; set; }

    public Post(DBItem item, List<Vote> votes)
        : base(item, votes)
    {
        Summary = (string) item["Summary"];
        Link = new UriBuilder((string) item["Link"]).Uri;
        ImageUrl = new UriBuilder((string) item["ImageUrl"]).Uri;
    }
}

这些类的其他共同点是大部分时间它们将作为排序集合返回。这里的困难是你不能将集合嵌入到抽象类中,因为没有办法实例化抽象类本身。

到目前为止,我所做的工作是将 Sort 方法作为此处显示的摘要的一部分:

    protected static List<ESCO> SortedItems(List<ESCO> escoList, ListSortType sortType)
    {
        switch (sortType)
        {
            case ListSortType.Hot:
                escoList.Sort(delegate(ESCO p1, ESCO p2) { return p2.HotScore.CompareTo(p1.HotScore); });
                return escoList;
            case ListSortType.Top:
                escoList.Sort(delegate(ESCO p1, ESCO p2) { return p2.VoteTotal.CompareTo(p1.VoteTotal); });
                return escoList;
            case ListSortType.Recent:
                escoList.Sort(delegate(ESCO p1, ESCO p2) { return p2.Created.CompareTo(p1.Created); });
                return escoList;
            default:
                throw new ArgumentOutOfRangeException("sortType");
        }
    }

这让我可以在我的 Inherited Children 课程中使用它:

    public static List<Post> Posts(SPListItemCollection items, ListSortType sortType, List<Vote> votes)
    {
        var returnlist = new List<ESCO>();
        for (int i = 0; i < items.Count; i++) { returnlist.Add(new Post(items[i], votes)); }
        return SortedItems(returnlist, sortType).Cast<Post>().ToList();
    }

这行得通,但感觉有点笨拙。我仍然在我的子类中重复很多代码,我觉得这种演员表是一种不必要的性能降低。

我如何最好地提供一种方法来返回基于抽象类的对象的排序列表,这些抽象类以相同的方式排序,具有相同的属性?

【问题讨论】:

    标签: c# sorting inheritance abstract-class instantiation


    【解决方案1】:

    看起来不需要抽象类,因为没有抽象成员。最好只使用一个具体的基类(如果需要,添加 virtual 成员)?

    更好的是,使用包含排序所需的所有成员(分数、投票等)的界面;将接口的集合传递给您的排序方法。

    编辑这是一个简化的例子:

    internal interface ISCO
    {
        double HotScore { get; set; }
    }
    
    class SCO : ISCO
    {
        public double HotScore { get; set; }
    
        public static IEnumerable<T> Sort<T>(IEnumerable<T> items) where T : ISCO
        {
            var sorted = items.ToList();
            sorted.Sort();
            return sorted;
        }
    }
    

    然后您可以对每个派生类使用该单一排序方法:

    List<Post> PostItems = // ...
    IEnumerable<Post> sorted = SCO.Sort<Post>(PostItems);
    

    【讨论】:

    • 那么属性是否存在于接口中,然后有一个具体基类具有所有方法,然后从该具体基类继承?
    • @Wesley 是的,我认为这样更好,因为这样您就可以将 IEnumerable 传递给排序方法。您可以从接口拆箱到派生类型,而不是强制转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    相关资源
    最近更新 更多