tags:

views:

50

answers:

3

It probably isn't possible, but I want to check if something like this can be expressed in a simple way:

// obviously doesn't work
class Foo<T> : IFoo<T1,T2>
    where T: Bar<T1,T2>
{
    // ...
    Baz<T1,T2> getBaz(){...}
}

Right now I declare Foo<T1,T2>, but I don't like it semantically, and the only way to get the constraint is to also list Bar in Foo's generic parameter list and I am looking to reduce the redundancy, not add to it.

EDIT: Baz<T1,T2> should be a return type, not method name

+4  A: 

The problem with this, is that it doesn't define what T1 and T2 are.

You could do:

class Foo<T> : IFoo<int,string>
    where T: Bar<int,string>
{
    // ...
    void Baz(){...}
    // can call e.g. Qux<int, string>();
}

And you could do:

class Foo<T, T1, T2> : IFoo<T1,T2>
    where T: Bar<T1,T2>
{
    // ...
    void Baz(){...}
    // can call e.g. Qux<T1, T2>();
}

But as it is, there's no way of knowing what T1 and T2 are (a human can't even guess at what you're trying to do, so there's no way for the compiler to deduce it).

Jon Hanna
that's what I thought.....T1 and T2 could be included implicitly, but I guess that's just an overkill for this......but thank you
alh84001
Implicitly from where though?
Jon Hanna
+1  A: 

The type parameters required to create a runtime type for a given generic must be declared in the angle brackets with the generic's class name:

class Foo<T, T1, T2> : IFoo<T1, T2> 
          where T: Bar<T1, T2>
{
   //...
   void Baz() {...}
}

Basically, since Foo<x,y,z> is unique for any given combination of x, y, and z, they must all be declared "up top".

Note that you don't need to declare 'T1, T2' with Baz, however - those type parameters are already defined for the class. You can find more in the ECMA spec for generics

Philip Rieck
thank you.....I mixed up return type and method name when writing the question, but it doesn't change the meaning significantly though
alh84001
+1  A: 

You could create a wrapper class around it, but I doubt this is better than your original solution:

  public class FooWrapper<T1, T2>
  {
     public Foo<Bar<T1, T2>> FooObj;

     public FooWrapper()
     {
        FooObj = new Foo<Bar<T1, T2>>();
     }

     public class Foo<T> : IFoo<T1, T2> where T : Bar<T1, T2>
     {
        // ...
        public void Baz() 
        {
           Type t1 = typeof(T1);
           Type t2 = typeof(T2);
        }
     }
  }
SwDevMan81
thank you on an imaginative solution.....I'll refactor the `FooWrapper` constructor to a static method, but that is basically it :)
alh84001