C# 对不同的实体类使用相同的基窗体
我目前正在从事一个C#项目,其中一个主基表单由其他几个表单派生。我使用一个实体类来处理系统中表示的每个实体的数据操作:项、wharehouse、帐户等。这意味着每个派生形式都使用自己的DAO类型 我从这些派生形式中调用基本功能很好,我现在要讨论的是:由于每个形式都有不同的实体类,我需要为每个派生类指定一个特定的方法,而基本形式和派生形式之间的唯一区别是实体类的类型 我有这样的想法:C# 对不同的实体类使用相同的基窗体,c#,polymorphism,C#,Polymorphism,我目前正在从事一个C#项目,其中一个主基表单由其他几个表单派生。我使用一个实体类来处理系统中表示的每个实体的数据操作:项、wharehouse、帐户等。这意味着每个派生形式都使用自己的DAO类型 我从这些派生形式中调用基本功能很好,我现在要讨论的是:由于每个形式都有不同的实体类,我需要为每个派生类指定一个特定的方法,而基本形式和派生形式之间的唯一区别是实体类的类型 我有这样的想法: int id; int.TryParse(key.Text, out id);
int id;
int.TryParse(key.Text, out id);
instance1 = adapter1.Populate(id);
if (instance != null)
{
bindingSource.DataSource = instance1;
this.GoEdit();
this.MarkDeleted();
}
例如,阻止我使用此方法的泛型版本从我的DB填充实体类的原因是,在父窗体中定义这些方法时,我必须为没有实现的实体使用基类,因此最终我不能使用泛型版本
在每个派生形式的实现中,为了将实例设置为特定的实体类,我不得不一次又一次地复制这些代码(对于这种类型的每个方法),这让我很烦恼。应该有另一种方法,我希望以前有类似情况的人能帮助我找到解决方法。在基本表单中放置一个受保护的字段来存储基本实体类类型的引用如何。派生表单的构造函数可以将此字段设置为适当的派生实体类。您问题中的代码基本上可以是基本形式。看起来您可能需要使用一个。这将允许您实现从该接口继承的类,但为
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);
}
您能详细说明instance1和adapter1是什么吗?在我的基本表单中,instance1是基本实体类,adapter1是包含所有更新/插入/删除方法的数据访问类。我使用实体类作为表字段的映射,只是为了操作数据。。所以问题是,在我的基本表单中,instance1引用了所有实体的基类,而这些实体基本上是空的,我需要一种方法来调用每个派生表单的派生类。我尝试了这种方法,但您在基本表单中提到的成员应该有一个类型,并且该类型必须是您的基本实体类,因此,当您从派生类调用任何特定方法时,基类中的空方法定义就是被调用的方法。不应该是。整个继承点(或至少一点)是,派生类型的对象可以分配给其基类型的变量(在本例中为字段),并且成员访问将解析为继承链中派生最多的类中的成员重写。因此,如果
Foo
有一个成员Bar
,并且DerivedFoo
继承Foo
并覆盖Bar
,那么Foo-fooVar=new-DerivedFoo();fooVar.Bar()
将执行Bar()
方法重写,该方法在DerivedFoo
中声明。我不知道为什么,可能我遗漏了什么。但是它在基类上有虚拟声明。基类方法应该标记为virtual
,派生类中的方法必须具有相同的签名,并且标记为override
。很抱歉,这只是挂起了,工作时间很疯狂。。无论如何,现在我看到了派生方法调用的问题所在:它们的签名都不同。每一个都返回一个特定类型的实体,而不是在基类定义中声明的基ECLASS类型。这似乎是一个很好的方法,无论如何,我这里的问题是Populate()的每个特定实现都将返回自己的不同类型,因为我使用实体类来封装与实体相关的所有数据。。因此,我在接口定义中为iPopulate()提供了一个基本返回类型,并为每个实现提供了一个不同的派生类型。
Populate Warehouse
Populate Item