1

簡単な質問があります。基本クラスのProductがあります。そして、ブレスレット、イヤリング、リングなどの派生クラス。ただし、リングクラスには追加のプロパティがあります。

そのサイズプロパティに到達し、以下のコードのメソッドでそれを使用するにはどうすればよいですか。

public class Product
{
    public int id;
    public string title;
}

public class Bracelet : Product
{

}

public class Earring : Product
{

}

public class Ring : Product
{
    public int size;
}

Product product;
if(category = 1) // this is a  Bracelet
{
    product = new Bracelet();
}
else if(category = 2) // this is a Earring
{
    product = new Earring();
}
else if(category = 3) // Wola, this is a ring
{
    product = new Ring();
    product.size = 4; // I cant reach size.. I need to assign size of the ring to decrease stock correctly.
}

product.decreaseStock();
4

5 に答える 5

4

最初にローカルで値を宣言するだけです。

else if (category == 3) 
{
    var ring = new Ring();
    ring.size = 4;
    product = ring;
}

このようにしてRing、ブロック内の変数にアクセスできますifが、より一般的なproduct変数にも割り当てられます。

または、初期化構文を使用することもできます。

else if (category == 3) 
{
    product = new Ring { size = 4 };
}
于 2012-06-13T23:18:05.813 に答える
1

Kirk Wollの答えはおそらく最良ですが、別の解決策は「as」キーワードを使用することです。

(product as Ring).size = 4;

またはそれをキャストするには:

((Ring)product).size = 4;

また、代入演算子(=)と等式演算子(==)を混同しないように注意してください。たとえば、if(category == 3)

于 2012-06-13T23:23:15.920 に答える
0

ジェフリー・リッチターのCLRをC#で読んだ方がいいでしょう。

ringCLRはこのオブジェクトがリングであることを認識しないため、参照によってプロパティを参照することはできませproductん。そのため、CLRではサイズを変更できません。代わりに、以下を使用する必要があります。

Ring ring = new Ring();
ring.size = 4;

参照を介してこのプロパティに到達する場合productは、基本クラスで宣言する必要があります。

于 2012-06-13T23:21:15.133 に答える
0

RingのdecreaseStockメソッドをオーバーライドする必要があります。

したがって、製品では、最初に在庫減少方法を仮想としてマークします。

public class Product
{
    public int id;
    public string title;

    public virtual void DecreaseStock()
    {
        //your decrease logic here
    }
}

次に、リングで、オーバーライドメソッドでサイズを考慮した新しいロジックを配置します

public class Ring : Product
{
    public int size;
    public override void DecreaseStock()
    {
        //your special logic to deal with size here
    }
}
于 2012-06-13T23:20:42.333 に答える
0

この場合、を作成した直後にサイズを変更しているのでRing、次のようにではRingなく、として処理する方法がありProductます。

Ring ring = new Ring();
ring.size = 4;
product = ring;

私たちが持っていた場合、私たちはキャストできることProductを知っていました。Ringこれは、実際にはEarring:である場合、ランタイムエラーを引き起こします。

Ring ring = (Ring)product;
ring.size = 4;

またはもっと簡潔に:

((Ring)product).size = 4;

製品がそうであるRingかもしれないしそうでないかもしれない場合、そしてそうであるかどうかを設定したい size場合、もちろんテストすることができます:

if(product is Ring)
  ((Ring)product).size = 4;

多くの場合、テストとキャストを組み合わせるのが賢明です。

Ring ring = product as Ring;
if(ring != null)
  ring.size = 4;

多くのキャスティングは悪い兆候です。一般に、関心のあるレベルでオブジェクトを処理する必要があります。オブジェクトProductがであることがわかっている場合にのみ、オブジェクトを処理しますProduct。これを行うのに役立つ1つのことは、オーバーライドからメソッドまたはプロパティにアクセスすることです。

public class Product
{
  /* leave out other stuff */
  public virtual bool NeedsLargeBox
  {
    get
    {
      return false; // most products don't
      //(this property could also be abstract to force all derived
      //classes to decide upon how it operates)
    }
  }
}

public class Ring : Product
{
  public int size;
  public virtual bool NeedsLargeBox
  {
    get
    {
      return size > 100;
    }
  }
}

これで、コードRing自体が処理している間、コードは多数のオブジェクトを処理し、必要な大きなボックスの数と小さなボックスの数を決定できます。そのコードに直接アクセスする必要はありません(または、コードを知っていても、作成される前に記述して機能させることができます) 。 。sizeProductsizeRing

于 2012-06-13T23:35:35.867 に答える