1

我有一个简单的问题。有一个基类 Product。以及手镯、耳环和戒指等派生类。但是环类有一个额外的属性。

我将如何达到该 size 属性并在下面的代码中的方法中使用它。

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;
}

这样,您可以Ringif块中访问变量作为 a ,但它也将其分配给更通用的product变量。

或者,您可以只使用初始化语法:

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

柯克沃尔的答案可能是最好的,但另一种解决方案是使用“as”关键字:

(product as Ring).size = 4;

或铸造它:

((Ring)product).size = 4;

此外,请确保不要将赋值运算符 (=) 与相等运算符 (==) 混淆。例如,它应该是 if(category == 3)

于 2012-06-13T23:23:15.920 回答
0

在这种情况下,由于您在创建 之后才更改大小Ring,因此可以将其作为 aRing而不是 a来处理Product

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

在我们有 a 的情况下,Product我们知道Ring我们可以施放。如果它实际上是一个,这将导致运行时错误Earring

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

或更简洁地说:

((Ring)product).size = 4;

如果产品可能是 aRing也可能不是,并且我们想设置 size它是否是,我们当然可以测试:

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

通常将测试和演员相结合是明智的:

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

大量选角是一个不好的迹象。一般来说,我们应该在我们关心的级别处理一个对象——只有在Product我们只知道它是一个Product. 可以帮助做到这一点的一件事是通过覆盖访问方法或属性:

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它自己处理size,但代码可以处理一堆Product对象并决定有多少需要大盒子和多少小盒子,而无需size直接访问该代码(甚至知道它,它甚至可以在Ring创建之前编写和工作) .

于 2012-06-13T23:35:35.867 回答
0

您将不得不覆盖 Ring 中的 reductionStock 方法。

因此,在产品中,首先将减少库存方法标记为虚拟。

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

您最好通过 C# 阅读 Jeffrey Richter 的 CLR。

你不能通过引用来引用ring' 的属性product,因为 CLR 不会知道这个对象是环,这就是为什么 CLR 不允许你改变它的大小。相反,您应该使用:

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

如果您想通过product引用访问此属性,则应在基类中声明它。

于 2012-06-13T23:21:15.133 回答