4

I need help with casting generic paremetrs down to an interface.

I have prebaked code like this:

public interface InterFoo<T> {...}
public InterFoo<T> specialFoo<T>() where T : InterFoo<T> {...}
public InterFoo<T> regularFoo<T>() {...}

and i want to implement something like this

public InterFoo<T> adaptiveFoo<T>()
{
    if (T is InterFoo<T>)
        return specialFoo<T as InterFoo>();
    return regularFoo<T>();
}

at this point I cant find any solution so anything would be helpful, thanks.

EDIT: originally the functions had returned an int but that has a simpler solution that is incompatible with the code's intended purpose, the functions have been changed to request a generic type.

2
  • 3
    @elgonzo Google for Curiouly Recursive Template Pattern (CRTP for short). Eric Lippert wrote a good blog post on it IIRC Commented Jul 6, 2014 at 19:33
  • I revoke my first comment. Jeez, the type parameter for specialFoo method must be a class A : InterFoo<A> type. Oh, my brain hurts... Commented Jul 6, 2014 at 19:57

1 Answer 1

5

The is and as operators only compile for types that the compiler knows can be null (nullable value types or reference types).

You can try a call to IsAssignableFrom:

public int adaptiveFoo<T>()
{
  if (typeof(InterFoo<T>).IsAssignableFrom(typeof(T))
    return specialFoo<InterFoo>();
  return regularFoo<T>();
}

** Update to reflect changes in question **

Type constraints are, unfortunately viral, in order for your method to compile (when keeping with strict type checking from the compiler) you would need the constraint to be added to this method also. However, reflection can circumvent this restriction:

Your method would be:

public InterFoo<T> adaptiveFoo<T>()
{
  if (typeof(InterFoo<T>).IsAssignableFrom(typeof(T))
  {
    var method = typeof (Class1).GetMethod("specialFoo");
    var genericMethod = method.MakeGenericMethod(typeof(T));
    return (Interfoo<T>)method.Invoke(this, null);
  }

  return regularFoo<T>();
}
Sign up to request clarification or add additional context in comments.

2 Comments

thanks for the quick response, unfortunately, I oversimplified my example code. in truth I need the functions to return an Interfoo<T> type, which would be incompatible with the interfoo<interfoo<T>> that the specialfoo<interfoo>() would return. (I've incorporated the changes into the original question)
@rich.okeely the problem is that in order for specialFoo<InterFoo<T>> to pass the generic constraint, InterFoo<T> would have to implement InterFoo<InterFoo<T>> (since, from the constraint's perspective, the type T to check is InterFoo<T>)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.