【问题标题】:Two classes but same object两个类但相同的对象
【发布时间】:2019-03-29 13:58:27
【问题描述】:

我有 2 个表,tblA 和 tblB,具有相同的字段和类型。我通过 linq to sql 获取数据,所以我有 2 个部分类 clsTblA 和 clsTblB。

我有一个选择 tblA 或 tblB 的组合,我必须读取该表并进行一些查询。

我想要做的是避免重复代码以运行相同的方法。 所以现在我有了(伪代码):

if (combo == "A")
{
  List<clsTblA> listUserNow = ctx.clsTblA.Where(p => p.blabla).ToList();
  List<clsTblA> listUserLastYear = ctx.clsTblA.Where(q => q.blabla).ToList();
}
if (combo == "B")
{
  List<clsTblB> listUserNow = ctx.clsTblB.Where(p => p.blabla).ToList();
  List<clsTblB> listUserLastYear = ctx.clsTblB.Where(q => q.blabla).ToList();
}

但我有这样的想法(在伪代码中):

SupClsTable clsTblX = null;
if (combo == A)
  clsTblX = new clsTblA();
if (combo == B)
  clsTblX = new clsTblB();

List<clsTblX> listUserNow = tblX.QueryForNow();
List<clsTblX> listUserLastYear = tblX.QueryForLastYear();

是否存在这样的东西? 我也搜索了设计模式,但没有结果。

提前致谢。

编辑 1: 此时代码是这样的:

if (combo == A)
{
  using (DbDataContext ctx = new DbDataContext())
  {
      List<clsTblA> listUserNow = ctx.clsTblA.Where(p => p.blabla).ToList();
      List<clsTblA> listUserLastYear = ctx.clsTblA.Where(q => q.blabla).ToList();
  }
}
if (combo == B)
{
  using (DbDataContext ctx = new DbDataContext())
  {
      List<clsTblB> listUserNow = ctx.clsTblB.Where(p => p.blabla).ToList();
      List<clsTblB> listUserLastYear = ctx.clsTblB.Where(q => q.blabla).ToList();
  }
}

所以我有两次 listUserNow 和 listUserLastYear。 我怎样才能让我返回一个独特的

using (DbDataContext ctx = new DbDataContext()) 
{
    List<*something*> listUserNow = ctx.*something*.Where(p => p.blabla).ToList();
    List<*something*> listUserLastYear = ctx.*something*.Where(p => p.blabla).ToList();
}

独立于“if combo”? 提前感谢

【问题讨论】:

  • 你为什么不使用接口?就此而言,如果两个类都相同,为什么会有两个类?
  • 删除第二个表(和类),添加列(和属性),如typeA AND B ...现在你有一个表和一个类...问题已解决 (Where(p =&gt; p.blablam &amp;&amp; p.type="A"))
  • tblA 和 tblB 已从利益相关者那里设置..
  • @CodeIT,利益相关者给你要求,而不是数据库实现。如果他们坚持这样做,通常这不是一个好兆头
  • 我完全可以相信,您需要两个课程可能是有充分理由的。我会选择一个通用的基类,并尝试尽可能多地放在那里。然后将表 A 和表 B 类作为孩子。他们尽可能少,他们只是尽可能多地委托给基地。

标签: c# oop design-patterns


【解决方案1】:

您正在寻找的似乎是接口。即

interface ISampleInterface
{
    void SampleMethod();
}

class ImplementationClass : ISampleInterface
{
    // Explicit interface member implementation: 
    void ISampleInterface.SampleMethod()
    {
        // Method implementation.
    }
}

您可以在 Microsoft 文档站点 Microsoft Docs 上了解更多信息

编辑:清除。一旦两个类都从接口中删除,您就可以编写以下内容

if (combo == A)
  clsTblX = new clsTblA();
if (combo == B)
  clsTblX = new clsTblB();

如下

IClsTable clsTbl = (combo == A)? new ClsTblA() : new ClsTblB() // example

并像以前使用ClsTblAClsTblB 一样使用clsTbl,因为它们都遵循相同的结构并具有相同的属性和方法。

也许this dotnetfiddle example 可以帮助你理解这个解决方案的概念。

【讨论】:

  • 我的问题是创建一个包含 classTblA 和 classTblB 的(超级)对象。因此,该对象可以在运行时决定它是否必须作为 A 或 B 工作。
  • @CodeIT 让两个类都实现该接口。
  • @CodeIT 一个接口可以让你存储所有遇到接口的对象。
  • @Vulpex 感谢您的关注。好的,但是当我必须调用 IClsTable 的查询方法时,IClsTable 如何才能“理解”它必须作为 ClsTblA 或 ClsTblB 工作才能返回给我一个唯一的对象?
  • @CodeIT 你说ClsTblAClsTblB 是相同的。如果这些可以从表示类结构的接口中获取。如果您然后store list&lt;Interface&gt; 中的对象,则可以调用接口中定义的方法,因为确保类具有这些方法。这些方法在每个类中的工作方式可能不同,但它们必须具有相同的结构。
【解决方案2】:

虽然我个人认为接口对于您的用例来说是更好的选择,但您也可以实现类似的东西,这样您就可以轻松扩展。同样也可以针对界面进行投射。因此,每次添加新组合时,只需添加一个案例,它就可以轻松扩展。

public class ComboFactory
{
    public static SuperCombo GetComboClassInstance(string comboCode)
    {
        switch(comboCode)
        {
            case "A":
                return new ComboA();
            case "B":
                return new ComboB();
            //and so on
        }
    }
}

【讨论】:

    【解决方案3】:

    试试看这是不是你需要的:

    public interface iTbl
    {
        int Property1 { get; set; }
        string Property2 { get; set; }
    
        void WhatAreYou();
    }
    
    public class clsTblA : iTbl
    {
        public int Property1 { get; set; }
        public string Property2 { get; set; }
    
        public void WhatAreYou()
        {
            Console.WriteLine("I am a clsTblA!");
        }
    }
    
    public class clsTblB : iTbl
    {
        public int Property1 { get; set; }
        public string Property2 { get; set; }
    
        public void WhatAreYou()
        {
            Console.WriteLine("I am a clsTblB!");
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            List<iTbl> tbls = new List<iTbl>()
            {
                new clsTblA(),
                new clsTblB(),
                new clsTblB(),
                new clsTblA(),
                new clsTblA()
            };
    
            foreach (var tbl in tbls)
            {
                tbl.WhatAreYou();
            }
        }
    }
    

    输出:

    I am a clsTblA!
    I am a clsTblB!
    I am a clsTblB!
    I am a clsTblA!
    I am a clsTblA!
    

    【讨论】:

      猜你喜欢
      • 2020-07-15
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-13
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多