2009-01-26 72 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) { 
// .. 
}