2013-05-01 67 views
0

ok回到另一个问题......当你将基础对象指定为另一个对象时,基础对象变成了该对象,但仍然没有它的属性。如何在分配给基础对象时保留指定的对象属性?

public class MyObjectBase { 
     public void Begin() { 

    } 

{ 
public class OneOfMyObjects : MyObjectBase { 
     public void Begin() { 
     base.Begin(); 

    //do stuff 

} 
} 
public class ManagmentClass { 

public MyObjectBase myCurrentObject; 

//called a only one when the program starts 
public void Start() { 
    Mymethod(new OneOfMyObjects()); 

} 
//generic method 
public void Mymethod<T>(T Objectclass) where T : MyObjectBase { 
     myObject = Objectclass 
     myObject.Begin(); // compiler error, non existent in MyObjectBase 
     myObject.GetType().ToString() //returns "OneOfMyObjects" 

} 
} 

当然,编译器找不到“Begin()”,因为begin在MyBaseObject中原本不存在。 我正在做类似于Ruby的自定义语言到C#(上面)之间的转换,但是这种类似Ruby的语言没有遇到我遇到的这个“问题”。它似乎编译它。 .NET4中有什么可以解决这个我忘记的问题吗?

回答

1

给这个旋转。问题是你使用的基类没有提供Begin的定义(你知道,只是重申一遍)。所以,要做的是为基类提供一种方法来使用Begin()方法。在下面的例子中,MyObjectBase是一个抽象类,Begin()是一个抽象方法。这意味着MyObjectBase永远不会有Begin()的定义,但它会强制所有派生类为Begin()提供一个定义。因此,举例来说:

MyObjectBase obj1 = new MyObjectBase(); 
obj1.Begin(); //Won't Compile 

OneOfMyObjects obj2 = new OneOfMyObjects(); 
obj2.Begin(); //Compiles if and only if OneOfMyObjects 
//class has a definition for Begin(). 

而且,我通常用C++编程所以这可能不是100%的最佳实践为C#,但它的编译能力。我也改变了Begin的范围。当您希望派生类访问基类中的某些内容时使用Protected,但它不一定是处理衍生事件时使用的范围。 Begin从基类和派生类之外被访问,所以它需要公开。

public abstract class MyObjectBase 
{ 
    public abstract void Begin(); 
} 

public class OneOfMyObjects : MyObjectBase 
{ 
    public override void Begin() 
    { 

     //do stuff 

    } 
} 
public class ManagmentClass 
{ 

    public MyObjectBase myCurrentObject; 

    //called a only one when the program starts 
    public void Start() 
    { 
     Mymethod(new OneOfMyObjects()); 

    } 
    //generic method 
    public void Mymethod<T>(T Objectclass) where T : MyObjectBase { 
    MyObjectBase myObject = Objectclass; 
    myObject.Begin(); // Shouldn't throw an error any more 
    myObject.GetType().ToString(); //returns "OneOfMyObjects" 

    } 
} 
+0

从来没有想过这个谢谢 – Fornoreason1000 2013-05-01 15:21:00

2

好了,你可以使用动态类型:

dynamic myObject; 

...但你Mymethod方法不能真正接受MyObjectBase的任何实例......它必须有例如,方法是Begin。使用动态类型,只有当执行时不是这种情况时才会发现。

您应该考虑代码尝试实现的更高层次的目标,以及在C#中实现相同目标的最习惯方式,而不是直接移植某些为不同语言编写的代码,而是使用不同的语言。没有更多的信息,我们无法引导你。

+0

即使MyObjectBase已经开始它会运行通过MyObjectBase开始,试图运行的代码是通过OneOfMyObjects的myObject.Begin。 – Fornoreason1000 2013-05-01 14:25:56

+2

@ Fornoreason1000:关键是,除非'MyObjectBase'声明了一个(可能是抽象的)'Begin'方法,或者你改变了通用约束来约束'T'来实现一些与'Begin'的接口,编译器不知道是否或者不是你的实际类型有一个'Begin'方法。因此,无论您需要使用'dynamic'摆脱静态类型,还是重新考虑您的方法。我会建议后者。 – 2013-05-01 14:29:39

+0

或者我可以做一个基类的抽象基类,然后覆盖方法? – Fornoreason1000 2013-05-01 15:04:50

相关问题