Jay
Jay

Reputation: 2946

Casting generic function type arguments in c#

I have two generic functions that can take generic type arguments, and i have three main classes and lots of sub classes

Classes: Base, Normal, Special

Both Special and Normal inherit from base, special is a final class but normal has many child classes

My functions are as follows

public void doWork<T>() where T:Base
{
    list<T> = 
        typeof(T) == typeof(Special) ?
        (List<T>)Convert.ChangeType(GetObjectsSelectedFromSpecial(),typeof(List<T>)) : // this is very ugly
        (List<T>)GetObjectsSelectedFromNormal<T>(); // this will not compile
}
   

GetObjectsSelectedFromSpecial returns a list of Special, which is fine

GetObjectsSelectedFromNormal<T> looks like this, and can be passed any child of Normal

public List<T> GetObjectsSelectedFromNormal<T>() where T : Normal
{
    ...
    ExternalFunction<T>(); // this needs T to be of type `Normal`
    ...
}

but in the line

... : (List<T>)GetObjectsSelectedFromNormal<T>();

I get the error

The type 'T' cannot be used as type parameter 'T' in the generic type or method 'myProject.GetObjectsSelectedFromNormal()'. There is no implicit reference conversion from 'T' to 'Normal'.

Is there a way to cast generic type arguments? not an object of type T but cast/convert/enforce-the-type-of T itself? Everywhere I've looked it is only talking about casting variables to and from T

Edit: Base, Normal and Special are internal classes to a framework I do not have access to alter directly, so solutions involving altering the classes are not possible

Upvotes: 1

Views: 72

Answers (1)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37000

A generic function that checks for a specific type isn´t really generic, is it? So instead of having a single method that only delegates the call to another method based on the actual type, just have different methods for different types in the first place:

public void DoWorkBase() { ... }
public void DoWorkNormal() 
{
    var list = GetObjectsSelectedFromNormal();
}
public void DoWorkSpecial() 
{ 
    var list = GetObjectsSelectedFromSpecial();
}

Upvotes: 3

Related Questions