Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.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
OOP C#问题:让水果变成梨_C#_.net_Oop - Fatal编程技术网

OOP C#问题:让水果变成梨

OOP C#问题:让水果变成梨,c#,.net,oop,C#,.net,Oop,假设我有一个水果实例,它有一些属性集,我想把这些属性放到一个新的Pear实例中(因为这个特殊的水果恰好具有Pear的特性),那么实现这个效果的最佳方法是什么 例如,我们不能简单地把一个水果扔给一个梨,因为不是所有的水果都是梨: public static class PearGenerator { public static Pear CreatePear () { // Make a new generic fruit. Fruit genericFr

假设我有一个水果实例,它有一些属性集,我想把这些属性放到一个新的Pear实例中(因为这个特殊的水果恰好具有Pear的特性),那么实现这个效果的最佳方法是什么

例如,我们不能简单地把一个水果扔给一个梨,因为不是所有的水果都是梨:

public static class PearGenerator {
    public static Pear CreatePear () {

        // Make a new generic fruit.
        Fruit genericFruit = new Fruit();

        // Upcast it to a pear. (Throws exception: Can't cast a Fruit to a Pear.)
        Pear pear = (Pear)genericFruit;

        // Return freshly grown pear.
        return ( pear );
    }
}

public class Fruit {
    // some code
}

public class Pear : Fruit {

    public void PutInPie () {
        // some code
    }

}
谢谢

更新:


我无法控制“new Fruit()”代码。我的出发点是,我有一种水果可以搭配。我得设法把那个水果装进一个新梨里。可能一个接一个地复制所有属性?

因为您创建的水果不是梨


编辑:如果您已经有一个
水果
,并且需要从中创建一个
Pear
,那么是的,您别无选择,只能将所有属性复制到一个新的Pear对象。理想情况下,这应该在专门为此创建的
Pear
构造函数中完成。

Pear是一种水果


水果不一定是梨。

它不是梨。试着换掉你的电话线

Fruit genericFruit = new Fruit();
与:


由于创建的实例是一个
水果
,因此向下播放失败,要使其成为
,请将代码更改为

    // Make a Pear - it looks like a fruit, tastes like a fruit,
    // and quacks like a fruit. It must be a fruit.
    Fruit genericFruit = new Pear();

    // Downcast it to a pear. 
    Pear pear = (Pear)genericFruit;
向下转换查看的是实际类型,而不是声明的类型,但您不知道实际类型是什么(除非您使用is/as进行测试)。这就是为什么它有点危险,大多数人尽量避免沮丧


编辑:要把一个水果做成一个梨,你可以自己创建一个新的梨,并尽可能地初始化它。所有水果共有的一些特性可以复制,从水果到梨。但这也可能像是试图把一个方形的钉子塞进一个圆形的洞里,把你的比喻混在一起,最后变成了水果泥。

如果梨定义了一大堆新东西。。你创造了水果

如果你把水果向上抛给梨子,那么梨子里的所有额外的东西应该设置成什么


这些都是未定义的东西。因此,为什么它是不允许的

当您进行铸造时,实际上并没有更改任何数据,如果您愿意,只需更改“标签”。如果你把一个梨铸成了一个水果,那么它可以被铸成一个梨,但是如果它一开始就不是一个梨,那么铸法就不能把它变成一个梨。

就像叶甫根尼所说的那样,这样做是不合法的,因为它不安全。如果不允许,将超级类型向下转换为派生类型

有各种各样的方法来解决你的问题,都取决于你的情况


泛型、动态(仅限C#4.0)、抽象类、接口。

如果您不负责
Fruit
,而是
Pear
的作者,那么可能采用不同的设计会有所帮助:


最好将您的
Pear
类更改为更多的
FruitWrapper
类。此类将包含对
水果的引用
,而不是更具体的
水果
。它可以有自己的功能(这是您不想首先使用
水果
的原因),并将水果类型的功能传递给它内部的
水果
。如果它需要使用需要一个
结果的库代码,只需传递它所持有的一个就可以了。

继承是绝对必要的吗

。。。我认为梨->水果的例子让这变得很难。。。这是一个例子,对吗

如何创建您的Pear类,如:

public class Pear { 

    public Fruit {get; set;}

    public void Pear(add pear properties, Fruit fruit)
    {
         // assign pear properties
         Fruit = fruit;
    }

    public void PutInPie () { 
        // some code 
    } 

}
这可能并不理想,但却是一个想法

祝你好运


Patrick

您可以为Pear创建一个新的构造函数,它接受一个Fruit实例。

这个例子让我想起了中的一个。看一看关于继承与组合的有趣讨论。想想这个问题。要从一个对象映射到另一个对象,您可以使用。

这不是向上强制转换,而是尝试将超级类型“向下强制转换”为派生类型,这不是法律。您希望未知的水果做什么?你怎么能保证水果能够做这些梨形的事情呢?你真的不想让你的代码变成梨形的,是吗?{G} 是的,把它想象成“所有的梨都是水果(这就是为什么你可以从一个梨到另一个水果),但不是所有的水果都是梨(所以你不能强迫它是梨)”这是关键。了解这一点以及何时使用它,您就掌握了一个重要的OO概念。
public class Pear { 

    public Fruit {get; set;}

    public void Pear(add pear properties, Fruit fruit)
    {
         // assign pear properties
         Fruit = fruit;
    }

    public void PutInPie () { 
        // some code 
    } 

}