2009-01-26 68 views
0

我這是在參數採取的方法是一個接口對象最好的方法來檢查

這樣

private void SomeMethod(InterfaceA IUA) 

裏面的方法我有這樣

ClassD someVar = (ClassD)(((ClassC)((ClassB)IUA)).D); 
聲明

一切如果罰款和丹迪。但是,在某些情況下,對象IUA可能是ClassZ的實例而不是ClassB。所以在這種情況下,上面的行錯誤了。在做上述陳述之前,有沒有辦法找出對象真正屬於哪個類?如果我知道前手那麼我就可以有一個If語句,然後執行以下

ClassZ someVar = (ClassD)(((ClassC)((ClassZ)IUA)).Z); 

我來自Java的背景......在java中我知道我們的getClass()...這將是在等效。淨?

回答

0

我不認爲有必要將IUA投入ClassB。據我所知,您沒有使用任何ClassB方法。

7

真的不應該沒有很好的理由寫這樣的代碼。

這就是說:你可以使用is

if (a is ClassB) 
{ 
    ClassB b = (ClassB)a; 
} 
else if (a is ClassZ) 
{ 
    ClassZ z = (ClassZ)a; 
} 

...或as

ClassB b = a as ClassB; 
if (b != null) 
{ 
    // ... 
} 
6

嗯,首先,你是不是真的應該從接口垂頭喪氣的一類,除非你有一個真的這樣做的好理由。如果您需要ClassD功能,那麼您的方法應該接收ClassD,而不是InterfaceA。

令我困惑的另一件事是多重向下轉換。我使用Java和C#,我從來沒有見過需要做這樣的多重轉換。

最後,你可以使用操作符「是」找出某些類型是否從某一個類繼承或者實現某個接口,如

if (IUA is ClassD) 
{ 
    // do something 
} 
1

你可以做

if (someVar is ClassZ) 

哪返回TRUE,如果someVar是-一個ClassZ,

someVar.GetType() 

得到實際的類

1

如何

if(IUA is ClassB) 
    someVar = (IUA as ClassB).B; 
elseif (IUA is ClassZ) 
    someVar = (IUA as ClassZ).Z; 

這應該工作,但是你得到的強制性責罵,這是一個比較差的架構。

0

你可以做類似

If (IUA is ClassB) 
    //I am class b 

然而,考慮到你的方法採取的接口,我想如果你正在尋找讓回到實際的具體類型的問題你的設計。您是否可以重新創建可用於執行該方法操作的接口方法。

0

從MSDN:

public static void Test (object o) 
    { 
     Class1 a; 
     Class2 b; 

     if (o is Class1) 
     { 
     Console.WriteLine ("o is Class1"); 
     a = (Class1)o; 
     // do something with a 
     } 

     else if (o is Class2) 
     { 
     Console.WriteLine ("o is Class2"); 
     b = (Class2)o; 
     // do something with b 
     } 

     else 
     { 
     Console.WriteLine ("o is neither Class1 nor Class2."); 
     } 
    } 
1

什麼是經過界面,如果你的只是去投它遠點?您可能想重新評估設計,因爲這樣的代碼會破壞多態性的目的。 你也應該不是使用'是'來測試類型。既然你要拋出對象,你應該使用'as'並測試null。

1

好了,有幾個不同的選擇在這裏:

  • for Java的getClass()等效爲GetType();您可以使用typeof(...)在編譯時檢索您知道的類型的Type對象。這不是測試事情的最佳方式,除非你對確切的平等感興趣。

  • Java的instanceof運營商的等效是is運營商在C#:

    if (x is SomeType) ... 
    

    這可以用盒裝的值可以用來檢查值類型,太:

    if (x is int) ... 
    
  • 一個相關運算符是as運算符,它不會返回true或false,而是返回指定類型的引用。該類型必須是可爲空的類型(引用或可爲空值類型),結果爲原始值,但如果該值是適當類型的引用,則強類型爲目標類型,否則爲null。例如:

    object x = "hello"; 
    
    string y = x as string; // y = "hello" now 
    Stream z = x as Stream; // z = null now 
    

    在這種情況下,你要檢查的引用是否是特定類型的,然後用它該類型的引用,一個常見的模式是:

    object x = GetObjectFromSomewhere(); 
    string y = x as string; 
    if (y != null) 
    { 
        Console.WriteLine(y.Length); // Whatever 
    } 
    

    這比相當於什麼在Java中需要更高效:

    object x = GetObjectFromSomewhere(); 
    if (x is string) 
    { 
        string y = (string) x; 
        Console.WriteLine(y.Length); // Whatever 
    } 
    
  • 如果它的參考是一個錯誤錯誤的類型,只是施放 - 這樣,如果你有一個錯誤,你會得到一個異常,這幾乎肯定是當時最好的行爲。

0

您應該使用方法重載,這是它應該是什麼樣子:

private void SomeMethod(ClassB obj) { 
    DoMoreStuff(obj.B); 
} 
private void SomeMethod(ClassZ obj) { 
    DoMoreStuff(obj.Z); 
} 
private void DoMoreStuff(int val) { 
// .. 
} 
相關問題