2

I have the class PlayersCollection and I want to interface it in IWorldCollection. The probleme is about writing the declaration in the interface which cause me this error :

Assets/Scripts/Arcane/api/Collections/ItemsCollection.cs(17,22): error CS0425: The constraints for type parameter `T' of method `Arcane.api.ItemsCollection.Get<T>(int) must match the constraints for type parameter `T' of interface method `Arcane.api.IWorldCollection.Get<T>(int)'. Consider using an explicit interface implementation instead 

Here is my class and my interface. How to write a generic method implementation with a class constraint ?

public class PlayersCollection : IWorldCollection { public Dictionary<Type, object> Collection; public PlayersCollection() { Collection = new Dictionary<Type, object>(); } public T Get<T>(int id) where T: PlayerModel { var t = typeof(T); if (!Collection.ContainsKey(t)) return null; var dict = Collection[t] as Dictionary<int, T>; if (!dict.ContainsKey(id)) return null; return (T)dict[id]; } } } public interface IWorldCollection { T Get<T>(int id) where T : class;// Work when I change "class" to "PlayerModel". } 

Big thanks for your help :)

3 Answers 3

1

It seems to me that the following will meet the requirements, by pushing the generic type parameter up to the class/interface level:

public class PlayersCollection<T> : IWorldCollection<T> where T : PlayerModel { public Dictionary<Type, T> Collection; public PlayersCollection() { Collection = new Dictionary<Type, T>(); } public T Get(int id) { var t = typeof(T); if (!Collection.ContainsKey(t)) return null; var dict = Collection[t] as Dictionary<int, T>; if (!dict.ContainsKey(id)) return null; return (T)dict[id]; } } public interface IWorldCollection<T> where T : class { T Get(int id); } 

If I have missed something in the requirements, please let me know.

Sign up to request clarification or add additional context in comments.

2 Comments

Just a tip, you don't need a collection of dictionaries per typeof(T). Being within the generic PlayersCollection(T), the Collection instance is already unique to each T, and won't get mixed up. So it could be simply declared as Dictionary<int, T> Collection .
@Will: Thank you; updated to be Dictionary<Type, T> Collection as suggested.
1

I'm not sure why you need this interface, but maybe this will help:

public class PlayersCollection<T> : IWorldCollection<T> where T:PlayerModel { public Dictionary<Type, object> Collection; public PlayersCollection() { Collection = new Dictionary<Type, object>(); } public T Get(int id) { ... } } public interface IWorldCollection<T> where T:class { T Get(int id); } 

Comments

0

Try this:

public class PlayersCollection : IWorldCollection<PlayerModel> { public Dictionary<Type, object> Collection; public PlayersCollection() { Collection = new Dictionary<Type, object>(); } public PlayerModel Get<PlayerModel>(int id) { /// } } } public interface IWorldCollection<T> { T Get<T>(int id); } 

In your case, in the class implementing your interface, you adding more condition for your class:

  • where T : class in the interface
  • where T: PlayerModel in the class

If, for some reason, you need to add a constraint into your interface, you need to add an interface or base class, which will be placed to the interface declaration, and you'll have to derive from it in your PlayerModel class, like this:

public abstract class Model { } public class PlayerModel : Model { } public interface IWorldCollection<T> where T : Model { T Get<T>(int id); } public class PlayersCollection : IWorldCollection<PlayerModel> { /// public PlayerModel Get<PlayerModel>(int id) { /// } } } 

2 Comments

Thx you, but I have to keep T Get<T>(int id) for my implementation because this method will return some subclass of PlayerModel.
@DanielN Then you should follow other's answers and make your Collection class generic too.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.