我有一个方法,它接受一个参数是一个接口对象
像这样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()...在.net中会有什么相同的东西?
答案 0 :(得分: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)
{
// ...
}
答案 1 :(得分:6)
嗯,对于初学者来说,除非你有真的这样做的好理由,否则你不应该从接口转向课堂。如果您需要ClassD功能,那么您的方法应该接收ClassD,而不是InterfaceA。
让我感到困惑的另一件事是多重转型。我同时使用Java和C#,我从未见过像这样做多重演员的需要。
最后,您可以使用运算符“is”来查明某些类型是从某个类继承还是实现某个接口,如
if (IUA is ClassD)
{
// do something
}
答案 2 :(得分:1)
你可以做到
if (someVar is ClassZ)
如果someVar是-A ClassZ,则返回TRUE,
或
someVar.GetType ()
获得实际的课程
答案 3 :(得分:1)
怎么样
if(IUA is ClassB)
someVar = (IUA as ClassB).B;
elseif (IUA is ClassZ)
someVar = (IUA as ClassZ).Z;
这应该有效,尽管你得到强制责骂这是一个相当糟糕的架构。
答案 4 :(得分:1)
如果您要将其丢弃,通过界面有什么意义?您可能希望重新评估设计,因为这样的代码会破坏多态性的目的。 此外,你应该不使用'是'来测试类型。既然你要转换对象,你应该使用'as'并测试null。
答案 5 :(得分:1)
好的,这里有几个不同的选择:
Java的getClass()
的等价物是GetType()
;您可以使用typeof(...)
检索编译时所知类型的Type对象。这不是测试事物的最佳方式,除非你对确切的平等感兴趣。
Java的instanceof
运算符的等价物是C#中的is
运算符:
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
}
如果引用的错误是错误类型的错误,只需强制转换 - 如果你有一个错误就会抛出异常,这几乎肯定是最好的行为方式。那一点。
答案 6 :(得分:0)
我认为没有必要将IUA转换为ClassB。就我所知,你没有使用任何ClassB方法。
答案 7 :(得分:0)
您可以执行类似
的操作If (IUA is ClassB)
//I am class b
但是,鉴于您的方法正在使用接口,如果您希望回到实际的具体类型,我会质疑您的设计。您可以重新考虑创建一个可用于执行该方法操作的接口方法。
答案 8 :(得分: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.");
}
}
答案 9 :(得分:0)
你应该使用方法重载,它应该是这样的:
private void SomeMethod(ClassB obj) {
DoMoreStuff(obj.B);
}
private void SomeMethod(ClassZ obj) {
DoMoreStuff(obj.Z);
}
private void DoMoreStuff(int val) {
// ..
}