This post contains a lot of code, but I would really appreciate it if you took the some to read and understand it...and hopefully come up with a solution
Let's assume that I am structuring a network-game where the entities need to be drawn and some of them updated from the server accordingly.
The Drawable
class is in charge of drawing the entities on-screen:
class Drawable
{
public int ID { get; set; } // I put the ID here instead of having another
// class that Drawable derives from, as to not
// further complicate the example code.
public void Draw() { }
}
The data that is received from the server implements IData
with each concrete IData
holding different properties. Let's say we have the following data that the Player
and Enemy
will receive:
interface IData
{
int ID { get; set; }
}
class PlayerData : IData
{
public int ID { get; set; }
public string Name { get; set; }
}
class EnemyData : IData
{
public int ID { get; set; }
public int Damage { get; set; }
}
The game entities that should be updateable from the server implement IUpdateable<T>
where T
is IData
:
interface IUpdateable<T> where T : IData
{
void Update(T data);
}
Our entities are thus Drawable
and Updateable
:
class Enemy : Drawable, IUpdateable<EnemyData>
{
public void Update(EnemyData data) { }
}
class Player : Drawable, IUpdateable<PlayerData>
{
public void Update(PlayerData data) {}
}
So that's the basic structure of the game.
Now, I need to store a Dictionary
of these Drawable
and Updateable
objects, storing the Drawable
's ID as the key and a complex object that holds the Drawable
and Updateable
objects and their remote concrete IData
:
class DataHolder<T, T1> where T:Drawable, IUpdateable<T1> where T1:IData
{
public T Entity{ get; set;}
public IData Data{ get; set;}
public DataHolder(T entity, IData data)
{
Entity = entity;
Data = data;
}
}
As an example, say I currently have the following entities:
var p1 = new Player();
var p1Data = new PlayerData();
var e1 = new Enemy();
var e1Data = new EnemyData();
var playerData = new DataHolder<Player, PlayerData>(p1, p1Data);
var enemyData = new DataHolder<Enemy, EnemyData>(e1, e1Data);
I now need to have a Dictionary
that holds the entities' ID as a key (p1.ID
and e1.ID
) and their DataHolder
(playerData
and enemyData
) and their value.
Something like the following (the below code just shows what I want to do and thus it doesn't not compile):
Dictionary<int, DataHolder> list = new Dictionary<int, DataHolder>();
list.Add(p1.ID, playerData);
list.Add(e1.ID, enemyData);
How do I construct such a Dictionary?
[Update]
As regards usage, I will then need to be able to do the following:
foreach (var value in list.Values)
{
var entity = value.Entity;
entity.Update(value.Data);
}
I have also tried to change the design of DataHolder
to the following:
class DataHolder<T> where T:Drawable, IUpdateable<IData>
{
public T Entity{ get; set;}
public IData Data{ get; set;}
public DataHolder(T entity, IData data)
{
Entity = entity;
Data = data;
}
}
Then I tried something like the following:
var playerData = new DataHolder<Player>(p1, p1Data); //error
But that throws a compile-time error:
The type 'Player' must be convertible to 'IUpdateable<IData>' in order to use it as parameter 'T' in the generic class 'DataHolder<T>'
For what reason is this thrown? Player
implements IUpdateable<PlayerData>
and PlayerData
implements IData
. Is this an issue with variance? And is there any way around it ?