【问题标题】:Using same base form for different entity classes对不同的实体类使用相同的基本形式
【发布时间】:2011-04-10 23:33:48
【问题描述】:

我目前正在处理一个 C# 项目,其中一个主要的基本形式是由其他几种形式派生的。我使用实体类来处理系统中表示的每个实体的数据操作:项目、仓库、帐户等。这意味着这些派生形式中的每一个都使用自己的 DAO。

我可以很好地从这些派生形式调用基本功能,我现在正在努力解决的是:由于每个形式都有不同的实体类,我需要为每个派生类指定一个特定的方法,而唯一的区别是基类和派生类是实体类的类型。

我有这样的事情:

        int id;
        int.TryParse(key.Text, out id);

        instance1 = adapter1.Populate(id);

        if (instance != null)
        {
            bindingSource.DataSource = instance1;
            this.GoEdit();
            this.MarkDeleted();
        }

因此,例如,阻止我使用此方法的通用版本从我的数据库中填充实体类的原因是,在父表单中定义这些方法时,我必须为我的实体使用基类而没有实现,所以最后我不能使用通用版本。

困扰我的是,我必须在每个派生形式的实现中一遍又一遍地复制这段代码(对于这种类型的每种方法),只是为了将实例设置为特定的实体类。应该有另一种方法,我希望以前有类似情况的人可以帮助我找到解决方法..

【问题讨论】:

  • 您能否详细说明instance1 和adapter1 是什么?
  • 在我的基本形式中,instance1 是基本实体类,adapter1 是具有所有更新/插入/删除方法的数据访问类。我使用实体类作为来自表字段的映射只是为了操作数据..所以问题是在我的基本表单中 instance1 正在为基本上为空的所有实体引用基类,我需要一种调用派生类的方法对于每一种派生形式。

标签: c# polymorphism


【解决方案1】:

如何在基本表单中放置一个受保护的字段来存储基本实体类类型的引用。派生表单的构造函数可以将此字段设置为适当的派生实体类。您问题中的代码基本上可能只是基本形式。

【讨论】:

  • 我试过了,但是你在基表单中提到的那个成员应该有一个类型,并且那个类型必须是你的基实体类,所以事实证明,当你从派生调用任何特定方法时基类中的空方法定义是被调用的类..
  • 不应该。继承的全部意义(或至少一点)是派生类型的对象可以分配给它的基类型的变量(或在这种情况下的字段),并且成员访问将解析为成员覆盖在继承链中最派生的类中。所以如果Foo有一个成员Bar,并且DerivedFoo继承Foo并覆盖Bar,那么Foo fooVar = new DerivedFoo(); fooVar.Bar();将执行Bar()DerivedFoo中声明的方法覆盖。
  • 我不知道为什么,也许我错过了一些东西。但它在基类上有虚拟声明。
  • 基方法标记为virtual,派生类中的方法必须具有相同的签名并标记为override
  • 我很抱歉让这只是挂起,疯狂的工作时间.. 无论如何,现在我知道派生方法调用的问题出在哪里:签名对于所有人来说都是不同的。每一个都返回一种特定类型的实体,而不是在基类定义中声明的基本 ECLASS 类型。
【解决方案2】:

您似乎想使用interface。这将允许您实现从该接口继承的类,但为Populate 函数实现它们自己的功能。

假设你有下面的类结构:

interface iPopulate
{
   void Populate(int id);
}

class MyBaseClass
{
  //whatever
}

class Warehouse : MyBaseClass, iPopulate
{
   void Populate(int id)
   {
       Console.WriteLine("Populate Warehouse");
   }
}

class Items : MyBaseClass, iPopulate
{
   void Populate(int id)
   {
      Console.WriteLine("Populate Item");
   }
}

您可以在不指定继承类是什么的情况下填充每个数据。示例:

List<MyBaseClass> stuff = new List<MyBaseClass>();
stuff.Add(new Warehouse());
stuff.Add(new Items());
foreach(MyBaseClass i in stuff)
{
    int someId = 123;
    iPopulate pop = i as iPopulate;
    pop.Populate(someId);
}

这将输出:

Populate Warehouse
Populate Item

【讨论】:

  • 似乎是一个很好的方法,无论如何我的问题是 Populate() 的每个特定实现都将返回它自己的不同类型,因为我使用实体类来封装所有相关的数据到一个实体。出于这个原因,我在接口定义中有一个 iPopulate() 的基本返回类型和每个实现的不同派生类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 2016-08-24
  • 2017-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多