2016-08-22 78 views
-1

是否有可能在C#中重載構造函數,以便程序在參數是派生類時選擇使用一個構造函數,如果它是基類,則選擇不同的構造函數。例如區分方法參數中的基類和派生類

class BaseClass {...} 
class DerivedClass : BaseClass {...} 

class foo 
{ 


     public foo(DerivedClass bar) 
     { 
      //do one thing 
     } 

     public foo(BaseClass bar) 
     { 
      //do another 
     } 

} 

也就是說,我希望程序根據對象類型選擇正確的構造函數。

+0

你試過了嗎? – Blorgbeard

+2

這有一個非常糟糕的代碼氣味,好像你可能試圖違反https://en.wikipedia.org/wiki/Liskov_substitution_principle – itsme86

+0

你:_基於對象類型_你的意思是聲明類型的參數(也稱爲作爲編譯時類型),還是實際的運行時類型?解決方案取決於此。如果您想基於編譯時類型進行「分支」,您顯示的代碼已經完成了這項工作。 –

回答

1

我覺得你的問題的最佳答案是有點間接的,但最好接近回答您的問題將沿此線:

編輯:糾正不正確is語法的使用和使之更具體的

public foo(BaseClass foobar) { 
    if (foobar?.GetType() == typeof(BaseClass)) { 
     //do something 
    } 
    else { // do something different }  
} 

這樣說,我不認爲這是必然的結構代碼的最佳方式;基於對象類型做出決定可能是一個信號,表示現在是通過抽象/虛擬類和方法利用多態性的時候了。你更好關閉IMO做這樣的事情:

public BaseClass { 
    public virtual void DoSomething() {...} 
} 

public DerivedClass : BaseClass { 
    public override void DoSomething() {...} 
} 

public foo(BaseClass foobar) { 
    foobar.DoSomething();  
} 
+0

多態性的具體技術,我認爲你要使用的是單一調度的能力:https://en.wikipedia.org/wiki/Single_dispatch –

+1

如果(foobar是typeof(BaseClass))'不是一個有效的語法,你可以使用'if(foobar是BaseClass)',但如果運行時的'foobar'有任何派生自'BaseClass'的類型,那麼這就是真的。鑑於編譯時類型,這在實踐中確實是一個空檢查。你也可以嘗試像'if(foobar?.GetType()== typeof(BaseClass))'這樣的精確匹配的東西。最後,考慮'if(foobar是DerivedClass)'還是聲明一個變量'var dc = foobar作爲DerivedClass;',並在'if'語句中檢查它是否爲'null'。 –

+0

@jeppestignielsen - 很好的觀察。我的主要觀點是指導OP更多樣化的解決方案;我會用您的反饋更新我的答案 –

0

如果您在BaseClass的投你的對象的良好構造函數將被調用。 像這樣:

void Main() 
{ 
    var object2 = new DerivedClass(); 
    var temp = new Allo((BaseClass)object2); 
} 

public class Allo 
{ 
    public Allo(BaseClass value) 
    { 
     Console.WriteLine("baseclass"); 
    } 

    public Allo(DerivedClass value) 
    { 
     Console.WriteLine("derivedclass"); 
    } 
} 

public class BaseClass 
{ 
} 

public class DerivedClass : BaseClass 
{ 
} 

輸出:

baseclass 
1

我同意其他人,這感覺就像一個代碼味道,但如果你真的編譯代碼並運行它,你會發現它已經按照你想要的方式工作。例如,這正是你想要它做的,無論好壞。

class Program 
{ 
    static void Main(string[] args) 
    { 

     var b = new BaseClass(); 
     var d = new DerivedClass(); 

     var f = new foo(d); 
     //prints Derived Constructor 
     var e = new foo(b); 
     //prints Base Constructor 
    } 
} 

public class BaseClass { 

    public BaseClass() 
    { 
    } 
} 
public class DerivedClass : BaseClass 
{ 
    public DerivedClass() 
    { 
    } 
} 
class foo 
{ 


    public foo(DerivedClass bar) 
    { 
     //do one thing 
     Console.WriteLine("Derived Constructor"); 
    } 

    public foo(BaseClass bar) 
    { 
     Console.WriteLine("Base Constructor"); 
    } 

} 
0

當我寫程序的簡單版本如上圖所示,它並選擇正確的派生類方法時的構造與派生類調用。

[當我作爲大型項目的一部分進行測試時,我的行爲越來越奇怪......但是現在我意識到這些是由於我的代碼中的其他錯誤 - 提醒自己實際測試的東西 - 這是第一次在四年內我做了任何編程,所以我忘記了基本知識......]。