添加一组访问到一个属性,从一个抽象类派生,只有get访问类(Adding a set accesso

2019-06-26 14:13发布

我有一个抽象类,AbsClass实现接口, 的iCLASS。 iCLASS非有只得到存取几个属性。 AbsClass实现为抽象属性,以在从AbsClass派生的类中定义的iCLASS的属性。

因此,所有从AbsClass派生的类还需要通过具有get访问相同的属性来满足的iCLASS。 然而,在某些情况下,我希望能够以组访问添加到从iCLASS非属性。 然而,如果我尝试用一组访问来覆盖AbsClass的抽象属性我得到这个错误

ConcClassA.Bottom.Set无法重写,因为AbsClass.Bottom不具有可重写的set访问

见下面ConcClassA。

如果我有一个类,只是实现的iCLASS界面,但不能从AbsClass继承话,我可以添加一组访问与出的问题。 见下面ConcClassB。

我可能只是在AbsClass的各导出实现的iCLASS而不是直接AbsClass。 然而,我从我的设计,每一个AbsClass需要也是一个iCLASS非知道,所以我宁愿指定上涨的层次结构。

public interface IClass
{
    double Top
    {
        get;
    }
    double Bottom
    {
        get;
    }
}

abstract class AbsClass:IClass
{
    public abstract double Top
    {
        get;
    }

    public abstract double Bottom
    {
        get;
    }
}



class ConcClassA : AbsClass
{
    public override double Top
    {
        get { return 1; }
    }

    public override double Bottom
    {
        get { return 1; }

        //adding a Set accessor causes error:
        //ConcClassA.Bottom.Set cannot override because AbsClass.Bottom does not have an overridable set accessor

        //set { }
    }

}

class ConcClassB : IClass
{
    public double Top
    {
        get { return 1; }
        //added a set accessor to an interface does not cause problem
        set { }
    }
    public double Bottom
    {
        get { return 1; }
    }
}

更新

所以我觉得这会更有意义,如果我解释什么,我试图做的而不是使用抽象的例子。 我工作的一个建筑公司工作,这些都与建筑设计项目的业务对象。

我有一个抽象类RhNodeBuilding代表一个项目一个类型的建筑物。 有一些普通的功能,比如有地板的能力,即在RhNodeBuilding定义。 RhNodeBuilding也从另一个抽象类,允许它是一个更大的项目树结构的一部分继承。

从接口IBuilding定义只读属性,所有的建筑物应能提供如TopElevation,BottomElevation, 身高 ,NumberOfFloors,etc..etc ..请记住有没有获得其他建筑类型的数量RhNodeBuilding工具从RhNodeBuilding,但仍需要实现IBuilding。

现在我有一个从RhNodeBuilding派生两类:MassBuildingFootPrintBuilding。 MassBuilding通过由用户创建的3D形状限定。 塑造具有TopElevation并应通过相应的属性访问的BottomElevation,但你不应该能够通过更改属性编辑3D体积。

在另一方面FootPrintBuilding由封闭曲线和高度范围定义为挤出通过该曲线。 所以,不仅要在课堂上能够返回当前有哪些海拔只不过这些海拔也应该能够改变重新定义高度范围。

因此,在总结。 所有建筑(IBuildings)需要能够返回一个TopElevationBottomElevation,但不是所有的建筑应该允许TopElevationBottomElevation直接设置。 所有RhNodeBuildingsIBuildings和类从RhNodeBuilding派生可能会或可能不会需要能够直接设置TopElevationBottomElevation。

public interface IBuilding
{
    double Top
    {
        get;
    }
    double Bottom
    {
        get;
    }
}

abstract class RhNodeBuilding:IBuilding
{
    public abstract double Top
    {
        get;
    }

    public abstract double Bottom
    {
        get;
    }
}



class MassBuilding: AbsClass
{

   //mass building only returns Top and Bottom properties so it works fine
    public override double Bottom
    {
        get { return 1; }
    }

    public override double Top
    {
        get { return 1; }
    }

}


class FootPrintBuilding: AbsClass
{
    //Top and Bottom of FootPrintBuilding can both be retrieved and set
    public override double Top
    {
        get { return 1; }
        //adding a Set accessor causes error:
        //cannot override because RhNodeBuilding.Top does not have an overridable set accessor

        //set { }
    }

    public override double Bottom
    {
        get { return 1; }

        //adding a Set accessor causes error:
        //cannot override because RhNodeBuilding.Bottom does not have an overridable set accessor

        //set { }
    }

}

现在,它似乎是最好的选择是没有RhNodeBuilding实施IBuilding,而是有充分的从RhNodeBuilding派生实现IBuilding类。 这样我可以直接从IBuilding而不是作为覆盖定义属性。

abstract class AltRhNodeBuilding
{
    public abstract double Top
    {
        get;
    }
}


class AltFootPrintBuilding: IClass
{
    public override double Top
    {
        get { return 1; }

       //Can't add set access to overridden abstract property
        set { }
    }

    //No problem adding set accessor to interface property
    public double Bottom
    {
        get { return 1; }
        set {  }
    }
}

Answer 1:

这工作确实因为性能并不是真正的虚拟的方式 - 他们的存取方法。 因此,你不能覆盖set ,如果没有一个基类。

你可以做的是覆盖和阴影基类的实现,并提供自己的新的读/写性能。 我不知道有什么办法做到这一点没有层次结构中引入额外的类:

class AbsClassB : AbsClass
{
    public override double Top { get { return ((ConcClassB)this).Top } }
    public override double Bottom { get { return ((ConcClassB)this).Bottom } }
}


class ConcClassB :  AbsClassB
{
    new public double Top
    {
        get { ... }
        set { ... }
    }

    new public double Bottom
    {
        get { ... }
        set { ... }
    }
}

更好的方法是定义在受保护的虚拟方法正确AbsClass ,并实现Top.getBottom.get该法的条款。 然后,你可以直接覆盖该方法ConcClassB和阴影的属性,而不需要一个额外的类:

abstract class AbsClass : IClass
{
    public double Top
    {
        get { return GetTop(); }
    }

    public double Bottom
    {
        get { return GetBottom(); }
    }

    protected abstract double GetTop();

    protected abstract double GetBottom();
}

class ConcClassB :  AbsClass
{
    new public double Top
    {
        get { ... }
        set { ... }
    }

    new public double Bottom
    {
        get { ... }
        set { ... }
    }

    protected override double GetTop()
    {
        return Top;
    }

    protected override double GetBottom()
    {
        return Bottom;
    }
}


Answer 2:

我有点好奇,为什么你会想这些实现类具有公共setter方法不属于公共接口的一部分。 这听起来像你对我可能实际上希望这些比公众更受限制?

除此之外,我有一个很难的问题这种方法思考。 他们将“隐藏”从超的任何属性,但也有在超没有属性setter无论如何,这样似乎确定。 看起来这可能是最简单的解决方法。



Answer 3:

使用全局变量。



文章来源: Adding a set accessor to a property in a class that derives from an abstract class with only a get accessor