tags:

views:

55

answers:

3

Sorry for asking what seems like such an obvious question.

I have an "adapter" generic class of type T where T is a defined interface. I want to create a method in that class which takes a different type of generic adapter.

public interface ICommon { }
public class TypeOne : ICommon { }
public class TypeTwo : ICommon { }

public class Adapter<T> where T : ICommon
{
    void TakeAnotherType(Adapter<S> other)
    { }
}

This gives me a compilation error Cannot resolve symbol 'S'.

I would like to be able to do;

    MyOne one = new Adapter<TypeOne>();
    MyTwo two = new Adapter<TypeTwo>();
    one.TakeAnotherType(two);

If I change the method to take Adapter<T> then it complains that "two" isn't of type Adapter<TypeOne>

+8  A: 
void TakeAnotherType<S>(Adapter<S> other) where S:ICommon
{ }

Because the generic type T of Adapter is constrained to ICommon, it is important to also constrain S in the same way, as this is used as the generic type for Adapter<T>, so it must also satisfy the ICommon constraint.

spender
+1 - thanks, that's done the trick.
Dead account
+2  A: 

Just change

void TakeAnotherType(Adapter<S> other)

into

void TakeAnotherType<S>(Adapter<S> other) where S : ICommon

and it should work.

Daniel Brückner
+1 thanks, would have been struggling with that for a while
Dead account
+1  A: 

Once you have specified that a class is generic (by naming it Something<T>), every method within it is implicitly generic on that type T. To say that a method is generic on a different type, you have to specify that fact in the method name, by calling it SomeMethod<U>. The body of this method will then have access to both types, T (the type that the class is generic on) and U (the class that the method is generic on).

Note also that the two usual conventions for type parameters are T, U, V etc; or TSomething, TSomethingElse, TEvenMore. I don't think I've ever seen S used...

AakashM