Этот пост содержит много кода, но я был бы очень признателен, если бы вы взяли некоторые, чтобы прочитать и понять это ... и, надеюсь, придумали решение
Давайте предположим, что я структурирую сетевую игру, в которой сущности должны быть нарисованы, а некоторые из них соответствующим образом обновлены с сервера.
Класс Drawable
отвечает за вывод объектов на экран:
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() { }
}
Данные, полученные с сервера, реализуют IData
с каждым конкретным IData
, содержащим различные свойства. Допустим, у нас есть следующие данные, которые Player
и Enemy
получат:
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; }
}
В игровых сущностях, которые должны обновляться с сервера, реализовано IUpdateable<T>
, где T
равно IData
:
interface IUpdateable<T> where T : IData
{
void Update(T data);
}
Наши сущности, таким образом, Drawable
и Updateable
:
class Enemy : Drawable, IUpdateable<EnemyData>
{
public void Update(EnemyData data) { }
}
class Player : Drawable, IUpdateable<PlayerData>
{
public void Update(PlayerData data) {}
}
Итак, это основная структура игры.
Теперь мне нужно хранить Dictionary
этих Drawable
и Updateable
объектов, сохраняя идентификатор Drawable
в качестве ключа и сложный объект, который содержит объекты Drawable
и Updateable
и их выносной бетон 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;
}
}
В качестве примера, скажем, у меня в настоящее время есть следующие сущности:
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);
Теперь мне нужно иметь Dictionary
, который содержит идентификатор сущности в качестве ключа (p1.ID
и e1.ID
) и их DataHolder
(playerData
и enemyData
) и их значение.
Что-то вроде следующего ( приведенный ниже код просто показывает, что я хочу сделать, и поэтому он не компилируется ):
Dictionary<int, DataHolder> list = new Dictionary<int, DataHolder>();
list.Add(p1.ID, playerData);
list.Add(e1.ID, enemyData);
Как мне создать такой словарь?
[Update]
Что касается использования, мне нужно будет сделать следующее:
foreach (var value in list.Values)
{
var entity = value.Entity;
entity.Update(value.Data);
}
Я также пытался изменить дизайн DataHolder
на следующий:
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;
}
}
Затем я попробовал что-то вроде следующего:
var playerData = new DataHolder<Player>(p1, p1Data); //error
Но это приводит к ошибке времени компиляции:
Тип «Игрок» должен быть конвертируемым
в 'IUpdateable ', чтобы
использовать его в качестве параметра «Т» в
универсальный класс 'DataHolder '
По какой причине это выброшено? Player
реализует IUpdateable<PlayerData>
и PlayerData
реализует IData
. Это проблема с дисперсией? И есть ли способ обойти это?