0

I currently try to construct a generic interface that every (generic) class deriving it will have a method accepting a delegate that accepts the type parameter and returns another class of the same type, with only another type parameter.

I tried the following:

public interface GenericInterface<out T, out SomeDerived>
    where SomeDerived<T> : GenericInterface<T, SomeDerived>
{
    SomeDerived<NT> bind<NT>(bindee<T, NT, SomeDerived<NT>> bindFunc);
}

public delegate AnotherDerived<T2> bindee<in T1, out T2, out AnotherDerived>(T1 param)
    where AnotherDerived<T2> : GenericInterface<T2, AnotherDerived>;

public class Derived<T> : GenericInterface<T, Derived>
{
    Derived<NT> bind<NT>(bindee<T, NT, Derived<NT>> bindFunc);
}

But it fails to compile and I get this error:

Invalid token '<' in class, struct, or interface member declaration

What is the correct design in such case?

EDIT:

I understand the syntatic reason for the compiler errors. You cannot apply a generic type argument a parameter in a where clause. I am asking what is the best way to mimic such behavior.

KanHar
  • 13
  • 3
  • 2
    Can you show us that *weird* error - the complete and full error with all details, please. – marc_s Sep 14 '13 at 12:20
  • well maybe weird is not the correct term... The compiler don't like having <> in the "where" specification – KanHar Sep 14 '13 at 12:23
  • Invalid token '<' in class, struct, or interface member declaration; Invalid token '>' in class, struct, or interface member declaration; Invalid token '{' in class, struct, or interface member declaration; Syntax error, ':' expected – KanHar Sep 14 '13 at 12:25
  • 2
    OK, now please also tell **exactly WHERE** in your code you're getting this error! – marc_s Sep 14 '13 at 12:26
  • I agree with marc_s, questions **must describe the specific problem** – Sayse Sep 14 '13 at 12:26
  • `SomeDerived` is syntatically wrong in where constraint – Sriram Sakthivel Sep 14 '13 at 12:27
  • Wait... you want the Generic Type to have a Type Parameter of itself? Mind-Blown... – Meirion Hughes Sep 14 '13 at 12:35

1 Answers1

2

I'll go out on a limb here and say what you're trying to do here with the Generic is impossible; I'll remove if someone thinks I'm wrong.

So lets start with this

interface IFoo<T> where T : IFoo<T>{}
class Foo<T> : IFoo<T> where T : IFoo<T>{}
class Bar<T> : Foo<T> where T : IFoo<T>{}

Lets try to instanciate this;

var foo = new Foo< Bar< ....errr what now? ad infinitum... 

So to fix this, you need to redesign so you're classes looks more like this:

interface IBase {}
interface IFoo<out T> where T : IBase { }
class Foo<T> : IFoo<T> where T : IBase { }

which then allows:

IFoo<IBase> foo = new Foo<Base>();

[Addendum]

You can have function level generics that let you get around problems like these...

interface IFoo<out T> where T : IBase
{
    IFoo<TBind> Bind<TBind>(Action<T, TBind> bindFunc) where TBind : IBase;
}
Meirion Hughes
  • 24,994
  • 12
  • 71
  • 122