当前位置:  开发笔记 > 编程语言 > 正文

一种将基类型转换为派生类型的方法

如何解决《一种将基类型转换为派生类型的方法》经验,为你挑选了7个好方法。

我不确定这是否是一件奇怪的事情,或者是否有一些代码闻起来...但我想知道是否有某种方式(某种oop模式会很好)来"施放"基类型到其派生类型的形式.我知道这没有多大意义,因为派生类型将具有父级不提供的附加功能,这在其本身并非基本健全.但有没有办法做到这一点?这是一个代码示例,以便我可以更好地解释我在问什么.

public class SomeBaseClass {
    public string GetBaseClassName {get;set;}
    public bool BooleanEvaluator {get;set;}
}

public class SomeDerivedClass : SomeBaseClass {
    public void Insert(SqlConnection connection) {
          //...random connection stuff
          cmd.Parameters["IsItTrue"].Value = this.BooleanEvalutar;
          //...
    }
}

public static void Main(object[] args) {
    SomeBaseClass baseClass = new SomeBaseClass();
    SomeDerivedClass derClass = (SomeDerivedClass)baseClass; 
    derClass.Insert(new sqlConnection());
}

我知道这似乎很傻,但有没有办法完成这种事情?



1> Adam Wright..:

"管理"语言并不合理.这是向下转型,并有处理一下,整整你所说的原因,任何理智的一路下跌(子类,提供超过基类-在哪里呢这个"更"是从哪里来的?).如果您确实需要特定层次结构的类似行为,则可以将构造函数用于将基类型作为原型的派生类型.

可以用反射来构建一些处理简单情况的东西(更具体的类型没有添加状态).一般来说,只需重新设计即可避免此问题.

编辑:Woops,无法在基类/派生类型之间编写转换运算符.微软试图"保护你"对付自己的奇怪之处.好吧,至少他们没有像太阳那样差.


@KonradMorawski我指的是Java语言功能,旨在确保您编写"好"代码(其中"好"是他们的意见).我最讨厌被检查的异常(所以你*不能*只是忽略异常,永远).

2> Rob Fonseca-..:

尝试合成而不是继承!

在我看来,你最好将SomeBaseClass的一个实例传递给SomeDerivedClass(它将不再派生基类,并且应该重命名为这样)

public class BooleanHolder{       
    public bool BooleanEvaluator {get;set;}
}

public class DatabaseInserter{
    BooleanHolder holder;

    public DatabaseInserter(BooleanHolder holder){
        this.holder = holder;
    }

    public void Insert(SqlConnection connection) {
          ...random connection stuff
          cmd.Parameters["IsItTrue"].Value = holder.BooleanEvalutar;
          ...
    }
}

public static void Main(object[] args) {
    BooleanHolder h = new BooleanHolder();
    DatabaseInserter derClass = new DatabaseInserter(h);
    derClass.Insert(new sqlConnection);
}

查看http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html(第3页):

通过组合重用代码组合为Apple提供了另一种方法,可以重用Fruit的peel()实现.Apple不是扩展Fruit,而是可以保存对Fruit实例的引用,并定义自己的peel()方法,只需在Fruit上调用peel()即可.


虽然我赞成合成而非继承,但"苹果有果实"而不是"苹果是果实"的想法是我见过的最糟糕的例子.如果Apple定义了它自己的Peel方法,那么它就不再是Fruit的替代品 - 这类似于Fruit的整个概念.

3> Rob Sedgwick..:

就个人而言,我不认为在这种情况下使用继承的麻烦是值得的.而只是在构造函数中传递基类实例并通过成员变量访问它.

private class ExtendedClass //: BaseClass - like to inherit but can't
{
    public readonly BaseClass bc = null;
    public ExtendedClass(BaseClass b)
    {
        this.bc = b;
    }

    public int ExtendedProperty
    {
        get
        {
        }
    }
}



4> Maciej Hehl..:

向下转换是有道理的,如果你有一个派生类的对象,但它被基类类型的引用引用,并且由于某种原因你希望它返回由派生类类型引用引用.换句话说,您可以向下转换以反转先前向上转换的效果.但是,您不能拥有由派生类类型的引用引用的基类对象.



5> Donny V...:

我不是说我推荐这个.但是您可以将基类转换为JSON字符串,然后将其转换为派生类.

SomeDerivedClass layer = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(BaseClassObject));


*"我不是说我推荐这个."*

6> Derek Park..:

不,这是不可能的.在像C#这样的托管语言中,它只是不起作用.即使编译器允许,运行时也不会允许它.

你自己说这看起来很傻:

SomeBaseClass class = new SomeBaseClass();
SomeDerivedClass derClass = (SomeDerivedClass)class; 

那么问问自己,class实际上是一个实例SomeDerivedClass吗?不,所以转换毫无意义.如果需要转换SomeBaseClassSomeDerivedClass,则应提供某种转换,无论是构造函数还是转换方法.

听起来好像你的类层次结构需要一些工作.通常,不应该将基类实例转换为派生类实例.通常应该存在不适用于基类的数据和/或功能.如果派生类功能适用于基类的所有实例,则它应该被卷入基类或拉入不属于基类层次结构的新类.



7> Ark-kun..:

C#语言不允许这样的操作符,但您仍然可以编写它们并且它们可以工作:

[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Implicit(Base a) { ... }

[System.Runtime.CompilerServices.SpecialName]
public static Derived op_Explicit(Base a) { ... }

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有