C# 多态性:正确处理
我试图了解C#中的多态性/继承情况 我现在的课程是:C# 多态性:正确处理,c#,.net,inheritance,polymorphism,C#,.net,Inheritance,Polymorphism,我试图了解C#中的多态性/继承情况 我现在的课程是: Lease (the base class containing the general data) PrivateLease (inheriting from the Lease class) BusinessLease (inheriting from the Lease class) 我想要实现的是: Lease lease = new PrivateLease(); 目前这是可行的,但在执行此操作时,我无法访问PrivateLea
Lease (the base class containing the general data)
PrivateLease (inheriting from the Lease class)
BusinessLease (inheriting from the Lease class)
我想要实现的是:
Lease lease = new PrivateLease();
目前这是可行的,但在执行此操作时,我无法访问PrivateLease
对象上的属性。至少在不先将Lease
对象强制转换为PrivateLease
对象的情况下
我希望Lease
对象是PrivateLease
或BusinessLease
对象的常规对象,该对象保存其中一个对象的所有数据。然后,在向数据库插入/更新/删除数据时,我将询问首先确定要将数据插入哪些表的类型
我有一种奇怪的感觉,上面的方法不是解决这个问题的正确方法。有人对此有任何提示吗?:-)我在google上搜索过,读过我的编程书籍,每个人都建议使用基类,然后从基类继承到其他类
非常感谢任何帮助/提示
提前谢谢
编辑
我应该从一开始就详细说明一下,我很抱歉
上面提到的类只是保存来自ASP.NET解决方案UI的数据,以便通过数据访问层对数据库执行CRUD操作。因此,基本上这些类只包含一组用于保存数据的属性。即:
public class Lease
{
public int Id { get; set; }
public bool IsActive { get; set; }
public string TypeOfRental { get; set; }
public string RentalPeriod { get; set; }
public DateTime TakeoverDate { get; set; }
}
public class PrivateLease : Lease
{
public string Floor { get; set; }
public string Side { get; set; }
public int FloorSize { get; set; }
public int NumberOfRooms { get; set; }
}
等等
PrivateLease
和BusinessLease
类是不同的,因为现实世界中存在不同的租赁变量:-)
基本上,我可以只使用两个独立的PrivateLease
和BusinessLease
对象,但由于模型规定地址
对象可以容纳一个或多个租赁
对象,因此这不是一个选项
在我看来,无论是在ASP.NET前端还是在DAL?上,我都将经历一场巨大的铸造地狱:-/ 基本的基类方法是正确的 您需要做的是在基类中放置任何公共属性。然后,如果您有不同的业务规则,则可以使用虚拟函数实现这些规则,并以多态方式调用
abstract class Lease
{
public int MonthlyCost {get;set;}
public string CustomerName {get;set;}
// Declare that all Leases have to have an IncreaseCost method.
public abstract void IncreaseCost();
}
class PrivateLease : Lease
{
// Private leases are incremented by an absolute number (10).
public override void IncreaseCost()
{
MonthlyCost += 10;
}
}
class BusinessLease : Lease
{
// Business leases are incremented by 10%.
public override void IncreaseCost()
{
MonthlyCost *= 1.10;
}
}
// Somewhere in your code...
Lease lease = new PrivateLease();
// This call is polymorphic. It will use the actual type of the lease object.
lease.IncreaseCost();
在现代的OOD中,对于这种情况,您可以使用
接口
编辑:
在我看来,为了避免强制转换,您可以为多种目的使用多个接口。然后,PrivateLease
和BusinessLease
可以实施适当的措施
interface IWrite
{
string Data { get; set; }
void Write();
}
interface IRead
{
string Data { get; set; }
void Read();
}
public class Lease
{
//..
}
public class PrivateLease : Lease, IWrite, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
public void Write()
{
//..
}
}
public class BusinessLease : Lease, IRead
{
// other implementations
public string Data { get; set; }
public void Read()
{
//..
}
}
不要在consumer层决定(选择逻辑),而是让类自己决定:
// or you ILease interface if a parent class will not contain any shared logic
abstract class Lease
{
public abstract void Do();
// example of shared logic
protected void Save(Lease l) { }
}
class PrivateLease : Lease
{
public override void Do() { // private logic here }
}
class BusinessLease : Lease
{
public override void Do() { // business logic here }
}
用法:
Lease l = ...
l.Do(); // execute the logic
您可能希望创建用于创建对象的工厂:
static class LeaseFactory<T> where T : Lease, new() // constraint to require default constructor existence
{
public static Leas Create()
{
return new T();
}
}
静态类LeaseFactory,其中T:Lease,new()//要求存在默认构造函数的约束
{
公共静态Leas Create()
{
返回新的T();
}
}
在Lease类中添加名为DBUpdate的虚拟方法,并在两个派生类中重写它
假设某个实用程序类的LeaseDBOperation方法如下所示:
public static void LeaseDBOperation (Lease anylease)
{
anyleaase.DBUpdate();
}
您可以将此方法称为:
var pl = new PrivateLease();
..set all the properties of **pl**
//call this for db operations :
Utility.LeaseDBOperation(pl)
在LeaseDBOperation方法中,如果基于类型send,则将调用所需类的DBUpdate方法。Hi Anders,非常感谢您的输入:-)因此基本上我必须将PrivateEase和BusinessLease上的属性声明为公共虚拟字符串MyProperty{get;set;}?如果它只是一个简单的属性,则不应将其设置为虚拟属性。使属性
虚拟化
几乎没有任何好处。另一方面,方法通常值得创建virtual
@AndersAbel-PrivateLease
,BusinessLease
在覆盖增加成本之前,可能应该继承Lease
;)@当然,我已经编辑了我的答案。有趣的是,两个月来没有其他人看到它。。。谢谢像这样的条件实际上是多态性的倒退。看看这里:还有这里:,还有其他。@David:同意。使用多态性让类自己决定执行什么逻辑。对于那些喜欢SOLID的人来说,这违反了打开/关闭原则。将方法命名为“Lease”有点不太合适:)@NSGaga:Agree。重命名为justDo()
。嗨,abatishchev,非常感谢你的帮助:-)问题是我的类实际上并不包含任何逻辑,它们只是包含一组用于保存数据的属性(我想你可以将它们视为DTO,真的),因此在这种情况下将没有实际重写的方法:-)@bomortensen:“仅属性容器”通常被称为POCO,您可能已经遇到了这样的缩写。通常在MVC中,有两种方法来扩展逻辑:瘦模型和厚模型。第一种方法仅包含数据(纯POCO),第二种方法也包含逻辑。我认为您的案例适用于第二种方法。类似于LeaseRepository.Do()
将接受Lease
并调用Do()
。大家好,abatischev。我还没有真正深入了解POCO是什么,但对我来说,它似乎是第一款(薄型)似乎最适合我的需要,因为我的类中根本没有任何逻辑。它们只包含用于在UI和DAL之间保存/传输数据的属性。请参阅我的解决方案:嗨,Mouliyan,谢谢你的帮助:-)但是,如果我这样做:ILease lease=new PrivateLease();如果PrivateRelease对象上的属性不是通过ILease接口实现的,我将无法访问它们,我对此不感兴趣,因为Lease类应该保存Lease类型对象的所有常规数据。您可以为相关属性实现不同的接口。嗨,Dhananjay,谢谢您的输入:-)这是更多或更多ss我现在是怎么做的。在我的DAL上有一个CreateLease(租约租约),我在DAL中创建租约
var pl = new PrivateLease();
..set all the properties of **pl**
//call this for db operations :
Utility.LeaseDBOperation(pl)