【问题标题】:Does/why does WebViewPage need to be inherited from twice, for generic+non-generic?对于泛型+非泛型,是否/为什么需要从两次继承 WebViewPage?
【发布时间】:2020-01-09 15:38:29
【问题描述】:

我继承了一个代码库,并发现了一些我无法弄清楚为什么需要它的代码(以及 如果)。

这是一个自定义的ViewPage,但我们将完全相同的代码重复了两次——一次用于ViewPage,一次用于ViewPage<T>。

基本上:

public class MyPageBase : WebViewPage
{
    //A whole bunch of properties intended to be accessible on every page
}
public class MyPageBase<T> : WebViewPage<T>
{
    //The exact same properties. Doesn't actually use T anywhere. The code is literally identical.
}

有这么多重复的代码远非理想。更糟糕的是,我不明白为什么需要它。一些测试表明,顶部的 似乎 没有做任何事情,但我无法对所有视图进行全面搜索(这个 MyPageBase 用于数十个应用程序)。

所以我的问题是:对于泛型+非泛型,WebViewPage 是否/为什么需要从两次继承?

【问题讨论】:

    标签: c# generics viewpage


    【解决方案1】:

    首先它不会被继承两次你有两个相同的实现 第一类是通用的,其他非通用的。

    你还没有向我们提供内部代码,所以这里举个例子,说你有这样的东西..

    public class MyPageBase<T> : WebViewPage<T>
        {
            //The exact same properties
            private DbContext db;
            public MyPageBase()
            {
                db = new MPContext();
            }
    
            public List<T> Fill()
            {
                return db.Set<T>().ToList();
            }
    
            public T FillBy(object id)
            {
                return db.Set<T>().Find(id);
            }
        }
    

    那么为什么需要通用页面? 如果在所有页面中都有一些共同的任务,您只需制作一个通用方法来完成这项工作。下面是一个非常示例的用法。 假设您的 dbcontext 中有 USERS 和 ORDERS 表

    public class UsersPage<USERS>:MyPageBase<USERS>{
    
      public void Index()
      {
         var filledData = Fill<USERS>();
      }
    }
    
    public class UsersPage<ORDERS >:MyPageBase<ORDERS >{
    
      public void Index()
      {
         var filledData = Fill<ORDERS>();
      }
    }
    

    当然你可以很容易地做到这一点

    var filledData = db.USERS.ToList();
    

    你可以问为什么这么大惊小怪?实现通用方法,但有时会发生比获取所有记录等更复杂的场景。

    假设您有 20 多个表,并且您决定从每个表中仅填充 5 条记录。没有通用实现 你知道必须翻遍 20 多页并更改代码

    来自

    var filledData = db.TABLE_TYPE.ToList();
    

    到

    var filledData = db.TABLE_TYPE.Take(5).ToList()
    

    但是使用泛型你可以在下面的方法中修复它,你甚至可以让它参数化

    public List<T> Fill()
        {
            return db.Set<T>().Take(5).ToList();
        }
    

    你很安全..

    现在如果你要使用 MyPageBase 的非通用实现

    所有这些你需要做的事情,你必须一遍又一遍地写。

    当然,编写越来越多的代码会给你带来经验,但在一段时间后,当你在一个程序中工作时,尤其是在大规模程序中工作时,你希望让事情尽可能简单、易于理解和可维护......

    对不起,我的英语不好,

    我希望我说的很清楚,这对你有帮助!

    【讨论】:

    • 抱歉,我想我不是很清楚。 “完全相同的属性”是指代码实际上是相同的。它实际上并没有在任何地方使用 T。
    猜你喜欢
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 2011-10-12
    • 2011-03-05
    • 2010-09-18
    • 1970-01-01
    相关资源
    最近更新 更多