Reputation: 43
I have a method which is taking in a parameter that is a Interface object
like this
private void SomeMethod(InterfaceA IUA)
Inside the method I have a statement like this
ClassD someVar = (ClassD)(((ClassC)((ClassB)IUA)).D);
everything if fine and dandy. However, in certain cases the object IUA might be instance of ClassZ rather than ClassB. So in that case the above line errors out. Is there a way to find out, before doing above statement, that which class does the object really belong to? If i know that before hand then I can have an If statement and do the following
ClassZ someVar = (ClassD)(((ClassC)((ClassZ)IUA)).Z);
I come from java background...In java i know we have getClass() ...what would be the equivalent in .net?
Upvotes: 0
Views: 217
Reputation: 91865
You really shouldn't be writing code like this without good reason.
That said: you can use is
if (a is ClassB)
{
ClassB b = (ClassB)a;
}
else if (a is ClassZ)
{
ClassZ z = (ClassZ)a;
}
...or as
:
ClassB b = a as ClassB;
if (b != null)
{
// ...
}
Upvotes: 7
Reputation: 122132
You should use method overloading, this is how it should look:
private void SomeMethod(ClassB obj) {
DoMoreStuff(obj.B);
}
private void SomeMethod(ClassZ obj) {
DoMoreStuff(obj.Z);
}
private void DoMoreStuff(int val) {
// ..
}
Upvotes: 1
Reputation: 1500983
Okay, a few different options here:
The equivalent for Java's getClass()
is GetType()
; you can use typeof(...)
to retrieve the Type object for a type you know at compile-time. This isn't the best way of testing things though, unless you're interested in exact equality.
The equivalent of Java's instanceof
operator is the is
operator in C#:
if (x is SomeType) ...
This can be used with boxed values to check for value types, too:
if (x is int) ...
A related operator is the as
operator, which doesn't return true or false, but a reference of the type specified. The type has to be a nullable type (reference or nullable value type) and the result is the original value but strongly typed as the target type if the value is a reference of an appropriate type, or null
otherwise. For instance:
object x = "hello";
string y = x as string; // y = "hello" now
Stream z = x as Stream; // z = null now
In the case where you want to check whether or not a reference is of a particular type, and then use it as a reference of that type, a common pattern is:
object x = GetObjectFromSomewhere();
string y = x as string;
if (y != null)
{
Console.WriteLine(y.Length); // Whatever
}
This is more efficient than the equivalent to what's required in Java:
object x = GetObjectFromSomewhere();
if (x is string)
{
string y = (string) x;
Console.WriteLine(y.Length); // Whatever
}
If it's a bug for the reference to be of the wrong type, just cast - that way you'll get an exception thrown if you've got a bug, which is almost certainly the best course of action at that point.
Upvotes: 1
Reputation: 1552
What is the point of passing the interface if your just going to cast it away? You might want to re-evaluate the design as code like this defeats the purpose of polymorphism. Also you should not use 'is' to test the type. Since you are going to cast the object anyway you should use 'as' and test for null.
Upvotes: 1
Reputation: 2700
From 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.");
}
}
Upvotes: 0
Reputation: 63126
You could do something like
If (IUA is ClassB)
//I am class b
However, given that your method is taking an interface, I would question your design if you are looking to get back to the actual concrete type. Can you re-factor to create an interface method that you can use to perform the actions of that method.
Upvotes: 0
Reputation: 122132
How about
if(IUA is ClassB)
someVar = (IUA as ClassB).B;
elseif (IUA is ClassZ)
someVar = (IUA as ClassZ).Z;
That should work, though you get the mandatory scolding that this is a rather poor architecture.
Upvotes: 1
Reputation: 6796
You can do
if (someVar is ClassZ)
Which returns TRUE if someVar is-a ClassZ,
or
someVar.GetType ()
to get the actual class
Upvotes: 1
Reputation: 8153
Well, for starters, you're not really supposed to downcast from interface to a class, unless you have a really good reason to do so. If you need ClassD functionality, then your method should receive ClassD, not InterfaceA.
Another thing that confuses me is the multiple downcasting. I use both Java and C# and I've never seen the need to do a multiple cast like that.
Finally, you could use operator "is" to find out whether certain type inherits from a certain class or implements a certain interface, as in
if (IUA is ClassD)
{
// do something
}
Upvotes: 6
Reputation: 51150
I don't think it's necessary to cast IUA to ClassB. You're not using any of the ClassB methods as far as I can tell.
Upvotes: 0