Reputation: 235
I want to define a house having multiple (special and normal)rooms each having a collection of (special and normal)things.
I started using generics for my ThingCollection(and derived classes), but when I wanted to define my Room types I start having errors with my generic type defintions.
Does anyone know a proper way of defining my interfaces/classes so I won't get this error message?
Code:
namespace City.Street.House
{
// Thing(s)
public interface IThing{ }
public interface ISpecialThing : IThing { }
// Collection(s)
public interface ThingCollection<TThing> where TThing : IThing { }
public interface SpecialThingCollection<TThing> : ThingCollection<TThing> where TThing : ISpecialThing { }
// Room(s) // Error On TThing in both rows below:
public interface Room<TThingCollection> where TThingCollection : ThingCollection<TThing> { }
public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<TThing> { }
// House(s)
public interface House { }
}
Error message:
CS0246: The type or namespace name 'TThing' could not be found (are you missing a using directive or an assembly reference?)
Upvotes: 0
Views: 40
Reputation: 235
@Zohar Your well given answer made me refactor the code a little.
I used this part of your code:
// Room(s)
public interface Room<TThingCollection> where TThingCollection : ThingCollection<IThing> { }
public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<ISpecialThing> { }
Also I had to change the collections interfaces to this:
// Collection(s)
public interface ThingCollection<TThing> where TThing : IThing { }
public interface SpecialThingCollection<TSpecialThing> : ThingCollection<IThing> where TSpecialThing : ISpecialThing{ }
Without these collection changes it wouldn't work.
Thanks for the help, much appreciated!
Upvotes: 0
Reputation: 82474
You can't use TThing
as a type parameter in the generic constraint unless it's also defined in the method's signature as well - so Room<TThingCollection>
should become Room<TThingCollection, TThing>
-
but for this to work you need to add more constraints:
public interface Room<TThingCollection<TThing>>
where TThingCollection : ThingCollection<TThing>
where TThing : IThing
{ }
public interface SpecialRoom<TThingCollection<TThing>> : Room<TThingCollection>
where TThingCollection : SpecialThingCollection<TThing>
where TThing : ISpecialThing
{ }
Or you can use the interfaces you've declared as the generic constraints (change TThing
to IThing
and ISpecialThing
:
// Room(s)
public interface Room<TThingCollection> where TThingCollection : ThingCollection<IThing> { }
public interface SpecialRoom<TThingCollection> : Room<TThingCollection> where TThingCollection : SpecialThingCollection<ISpecialThing> { }
Upvotes: 1