views:

78

answers:

4

Hi All, I want to create a method which will take some base type as a parameter and compares and check if it is derived type and return the derived type based on that. For Example:

Class A : IBase
Class B : IBase

My method:

Public IBase GetData(IBase type)
{
 If type is A then 
  {
   //do smthing
   return A
  }
 If type is B
  {
   //do smthing
   return B
  }
} 

Please help.....

+3  A: 

I guess technically, using polymorphism properly should entirely remove the need to for the type check.

However, to declare the generic function where the type parameter must implement an interface is like so:

public TBase GetData<TBase>(TBase type) where TBase : IBase

If you really do want to continue with the specific type checking then you can use Type.IsAssignableFrom function.

public TBase GetData<TBase>(TBase type) where TBase : IBase
{
    if (typeof(A).IsAssignable(typeof(TBase)))
    {
        // Do the special case stuff
    }
    ...
}

But as I started out mentioning, perhaps it would be more appropriate to move your special case stuff into the IBase interface itself.

Reddog
+2  A: 

This:

public T GetData<T>(T type) where T : IBase
{
   ....
}
Aliostad
+4  A: 

You should take the steps you want to perform where your code is labeled //do something and encapsulate that into a method of your classes, let's call it DoSomething(). You're going to want to add a public method to the IBase interface, called DoSomething(). Then, both type A and type B will implement this interface and provide different implementations for this "Do Something" method.

Then, you're method would simply be:

public IBase GetData(IBase type)
{
    type.DoSomething();
    return type; //not sure what this is for, maybe you're actually wanting to return type.GetType() ??
} 

For more details on how you use polymorphism to remove the need for these types of if statements, see the article Replace Conditional with Polymorphism.

wsanville
A: 

Generics are a little overkill here. Let's try reflection:

IBase type = GetSomeObjectOfDescendantType();
IBase newType = (IBase)Activator.CreateInstance(type.GetType());

You can wrap it in a method

public class MyDuplicator
{
    public static object GetNotClone(object X)
    {
        return Activator.CreateInstance(X.GetType());
    }
}

More on CreateInstance here.

Of course, this applies only if your question was about returning new object of type A if object of type A is being put into. Something as a .Clone() but a freshly constructed one.

Daniel Mošmondor
*Note:* `Activator.CreateInstance` is pretty slow, generics with a `new()` constraint would be much more performant and at the same time more elegant (and get the benefits of compile-time checking).
Lucero
@Lucero: I agree completely, however, I was aiming for more readable approach here. There are security concerns with reflection, as well.
Daniel Mošmondor