4

いくつかのクラスがあり、他のクラス メソッドからサブクラスで定義されたプロパティにアクセスする際に問題があります。

と呼ばれる基本クラスとSectionいくつかのサブクラスがありSectionPlane : Sectionます。各サブクラスでは、異なるフィールドとプロパティのセットが定義されています (SectionPlaneではプライベート フィールド_tとパブリック プロパティtが見つかりますが、SectionExtruded : Section私はプライベート フィールド_Aとパブリック プロパティ 'A' を持っています)。

クラスセクション

// General section object
public abstract class Section
{
    public Section()
    {}
}

クラス プレーン セクション

// Section object representing a plane with thickness t
public class SectionPlane : Section
{
    private double _t;

    public SectionPlane(double t)
    {
        this.t = t;
    }

    public double t
    {
        get
        {
            return _t;
        }
        set
        {
            _t = value;
        }
    }
}

クラス 押し出し断面

// Section object of some geometry with cross section area A extruded along the element it is assigned to.
public class SectionExtruded : Section
{
    private double _A;

    public SectionExtruded(double A)
    {
        this.A = A;
    }

    public double A
    {
        get
        {
            return _A;
        }
        set
        {
            _A = value;
        }
    }
}

クラスのサブクラスからElementプロパティにアクセスしようとすると、問題が発生します。これらSectionは、要素などの基本クラスに設定されていないためSolid2D : Elementです。

クラス要素

public abstract class Element
{
    private Section _section;

    public Element(Section section)
    {
        this.section = section;
    }

    public Section section
        {
            get 
            {
                return _section;
            }
            set
            {
                _section = value;
            }
        }
    }
}

クラス ソリッド 2D 要素

// Solid2D elements can only have sections of type SectionPlane
public class Solid2D : Element
{
    public Solid2D(SectionPlane section)
        : base(section)
    {
    }

    public void Calc()
    {
        double t = section.t;    // This results in error 'Section' does not contain a definition for 't' and no extension method 't' accepting a first argument of type 'Section' could be found (are you missing a using directive or an assembly reference?)
    }
}

バー要素

// Bar elements can only have sections of type SectionExtruded
public class Solid2D : Element
{
    public Solid2D(SectionExtruded section)
        : base(section)
    {
    }

    public void Calc()
    {
        double A = section.A;    // This results in error 'Section' does not contain a definition for 'A' and no extension method 'A' accepting a first argument of type 'Section' could be found (are you missing a using directive or an assembly reference?)
    }
}

t基本クラスに含めることなく、自分のプロパティにアクセスする方法はありますSectionか? 使用するセクションのすべてが同じプロパティを持っているわけではないため、これは非常に役立ちます。

4

4 に答える 4

7

あなたはそれが唯一のことができることを知っているので、それSectionPlaneをキャストすることができます

double t = ((SectionPlane)section).t;

正しいタイプのセクションがあるかどうかわからない場合は、asキーワードを使用できます

double t = 0;
var sectionPane = section as SectionPlane;
if (sectionPane != null) {
    t = sectionPane.t;
}

asセクションに別の型がある場合は例外をスローしませんが、null代わりに戻ります。

または、単にテストすることもできます

double t = 0;
if(section is SectionPlane) {
    t = ((SectionPlane)section).t;
}

asただし、型をテストしてからキャストする必要があるため、これは を使用するよりもエレガントではありません。しかし、キャストはこのテストを内部で再度行います。

C# 7.0 で導入された新しいパターン マッチングを使用すると、次のように記述できます。

double t = 0;
if(section is SectionPlane sp) {
    t = sp.t;
}

しかし、そのようなテストを実行する必要がある場合、問題は、あなたのアプローチがオブジェクト指向の意味で正しいかどうかです。Calc-method を抽象クラスに移動し、Section各クラスが独自の計算を実行できるようにすると、型テストやキャストは不要になります。

Section

public abstract void Calc();

SectionPlane

public override void Calc()
{
    var x = t;
}

...

section.Calc();  // No casting or type test required.
于 2012-06-17T18:18:40.843 に答える
1

あなたのプロパティ「t」をセクションの基本クラスに入れると思います。

于 2012-06-17T18:22:23.413 に答える
0

以下にいくつかのオプションを示します。

  1. に変更Element.sectionSectionPlaneます。
  2. にキャストsectionします。SectionPlaneCalc()
  3. に追加tSectionます。
  4. プロパティを持つインターフェイス (例: IHasT) を作成し、これを実装して、 に変更します。tSectionPlaneElement.sectionIHasT
  5. (該当する場合) に変更public abstract class Elementpublic abstract class Element<T> where T : SectionsectiontypeTに変更して、makeSolid2D : Element<SectionPlane>
于 2012-06-17T18:13:07.350 に答える
0

要素の継承者が使用するセクションのタイプがわかっている場合は、要素の基本クラスをジェネリックにします。

 public abstract class Element<SectionType>
     where SectionType:Section
 {
    //....
 }

基本クラスを使用して、デフォルトの要素タイプを含めることができます。

 public abstract class Element:Element<Section>
 {
    //....
 }

また、既知の要素は強く型付けされたものを継承できます。

 public class Solid2D : Element<SectionPlane>
于 2012-06-17T18:15:33.030 に答える