Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 多态性:正确处理_C#_.net_Inheritance_Polymorphism - Fatal编程技术网

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

我试图了解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();
目前这是可行的,但在执行此操作时,我无法访问
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。重命名为just
Do()
。嗨,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)