2011-07-29 82 views
0

這樣的事情應該可以在C#中,對不對?方法重載和多態性重訪

public void Start() 
    { 
     Class1 x = new Class1(); 

     string s = Something (x); 

     Console.ReadKey(); 
    } 

    public string Something (IInterface obj) 
    { 
     return foo (obj); // <-- Problem line 
    } 

    public string foo (Class1 bar) 
    { 
     return "Class1"; 
    } 

    public string foo (Class2 bar) 
    { 
     return "Class2"; 
    } 

    interface IInterface {} 

    class Class1 : IInterface {} 

    class Class2 : IInterface {} 

回答

2

號你foo方法期望無論是Class1Class2。您傳遞的是IInterface,可能是Class1Class2。它不會編譯,因爲編譯器不知道要調用哪個重載方法。您必須將其轉換爲其中一種類型才能編譯。

或者,IInterface將包含foo方法,該方法不接受任何參數並返回它所屬的類。然後事情就可以走IInterface對象,然後調用obj.foo()

像:

interface IInterface 
{ 
    public string foo(); 
} 

class Class1 : IInterface 
{ 
    public string foo() 
    { 
     return "Class1"; 
    } 
} 

class Class2 : IInterface 
{ 
    public string foo() 
    { 
     return "Class2"; 
    } 
} 

public void Something(IInterface obj) 
{ 
    return obj.foo(); 
} 
+0

那不是返回obj.foo();而不是返回foo(obj); –

+0

哎呦,當然是!感謝您指出了這一點。 –

+0

這工作。我只是試圖去除服務調用中的條件邏輯,這就是我最終做的。 –

1
public string Something (IInterface obj) 
{ 
    return foo ((Class1)obj); 
    OR // There's no way compiler to know with method to call. 
    return foo ((Class2)obj); 
} 

public string foo (Class1 bar) 
{ 
    return "Class1"; 
} 

public string foo (Class2 bar) 
{ 
    return "Class2"; 
} 
+0

這只是修復了編譯但沒有完成目標。 –

+1

@Erik。你的目標是什麼?你不提。 –

+1

我沒有目標,但原始的海報似乎困惑爲什麼發佈的代碼將無法正常工作。我認爲這個答案不是特別有用,因爲它是。這並不能解釋爲什麼原始海報的代碼不起作用,它如何重新考慮工作。 –

0

號,其中非虛擬來電的是在編譯時確定的,所以根據不同的方法,你不能打電話運行時的類型。

什麼,你可能會尋找的是虛擬的方法:

public void Start() { 
    Class1 x = new Class1(); 

    string s = Something(x); 

    Console.ReadKey(); 
} 

public string Something (BaseClass obj) { 
    return obj.foo(); 
} 

abstract class BaseClass { 
    abstract string Foo(); 
} 

class Class1 : BaseClass { 

    public override string foo() { 
    return "Class1"; 
    } 

} 

class Class2 : BaseClass { 

    public override string foo() { 
    return "Class2"; 
    } 

}