2013-05-01 106 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

相關問題