Generics: Type parameter with type parameter

J

john

Hi to All

I would like to do something similar:

class Class1<T1>
{
}

class Class2<T2, T1> where T2: Class1<T1>, new()
{
public void M()
{
T2<T1> x;
}

Error: The type parameter 'T2' cannot be used with type arguments.

How to accomplish this task?

thx for help
 
S

Stefan L

Hi John,

Hi to All

I would like to do something similar:

class Class1<T1>
{
}

class Class2<T2, T1> where T2: Class1<T1>, new()
{
public void M()
{
T2<T1> x;
The type parameter T2 already represents the type (or subtype)
Class1<T1>, not Class1<>.
When writing T2<T1> C# interpretes this like Class1<T1><T1>, which will
obviously not work.

Try just typing T2 x;
}

Error: The type parameter 'T2' cannot be used with type arguments.

How to accomplish this task?

thx for help

HTH,
Stefan
 
M

Marc Gravell

Well in your code, T2 is already defined as a discreet " : Class1<T1>", and
so there isn't much left to define; are you sure you don't just need T2 x =
new T2();?

If not, can you clarify how you intend to use it? Perhaps with more
penetrable class names so we can see what you are trying to do?

Marc
 
J

john

Hi thx for the fast answer,

A would like to use a type and its type parameter both as type parameter in
a third class

Sample:

class NonGenericClass
{
}

class1<T> where T: NonGenericClass
{
}
class2<T> where T: NonGenericClass
{
}

class3<T1, T2> where ?what to write here?
{
public void M()
{
T1<T2> x = new T1<T2>();
}
}
and use this somewhere:

class3<class1, NonGenericClass> a;
class3<class2, NonGenericClass> b
....

thx for help
 
S

Stefan L

As just stated above, use:

class3<T1, T2> where T1 : Class1<T2>, new()
{
public void M()
{
T1 x = new T1();
}
}

class3<class1, NonGenericClass> a
class3<class2, NonGenericClass> b

I assume class2 is inheriting from class1...

HTH,
Stefan
 
M

Marc Gravell

You can't; there is no such thing as class1 nor class2; only class1<T> and
class2<T>

You could use, for instance class3<T>, and then

class3<class1<NonGenericClass>>
or
class3<class2<SomethingInheritedFromNonGenericClass>>

however, you cannot have a condition in the form you have expressed, as it
would make no sense as the condition could not possibly be evaluated in any
way at compile time. You could perhaps use some kind of interface, but
without concrete, meaningful examples of what you are trying to do it is
very hard to answer. By concrete, I mean something like below - annd *even
then* I'm not sure why I would want to do this... what you are trying to
achieve is probably more important than how you are trying to do it, as I
suspect there is a better way...

Marc

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
abstract class Animal {}
class Dog : Animal {}
class AnimalCollection<T> : Collection<T> where T : Animal {}
class AnimalList<T> : List<T> where T : Animal {}
class AnimalWalker<TAnimalType, TCollectionType>
where TCollectionType : IEnumerable<TAnimalType>
where TAnimalType : Animal{ }

class Program {
static void Main()
{
AnimalWalker<Dog, AnimalList<Dog>> dogWalker = new
AnimalWalker<Dog,AnimalList<Dog>>();
AnimalWalker<Animal, AnimalCollection<Animal>> petWalker = new
AnimalWalker<Animal, AnimalCollection<Animal>>();

}
}
 
A

Adam Calderon

Hello John,

From what I can see I think there are a couple of things you should look
at. I have modified your code to show what I am talking about. One of the
things I found odd was that you were trying to use T2 in any form like this.
The purpose of constraints is to be able to (1) enforce that the correct
type is passed in and (2) hopefully to work with the exposed properties and
methods of that type. Two, that by not having either a member variable that
is assigned during the constructor calll or parameter passed in via a method
or property, the value of T2 is really nothing so you won't really be able
to use it.



public class Class1<T1>
{
Class1(){}

private int myVar;

public int MyProperty
{
get { return myVar; }
set { myVar = value; }
}

}

public class Class2<T2, T1> where T2: Class1<T1>, new()
{
//option 1 to have member variables and assign them in a constructor
T2 t2;
T1 t1;

Class2(T2 t2, T1 t1)
{
this.t1 = t1;
this.t2 = t2;
}

//option 2 to have the variable passed in.
public void M(T2 myT2)
{
myT2.MyProperty = 100;
}
}

Adam Calderon [C# MVP]
http://blogs.interknowlogy.com/adamcalderon
 
S

Stefan L

.... which will not work unless you type

class3<class1<NonGenericClass>, NonGenericClass> a

Sorry, but I see no chance to get aroud this inconvenience in typing.
Automatic type determination by C# will only be performed on method
calls, not for classes on variable declaration...

HTH,
Stefan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top