Для начала несколько занятий:
public abstract class Component
{
GenericSystem mySystem;
public Component() { mySystem = null;}
public void SetSystem(GenericSystem aSystem) { mySystem = aSystem; }
}
public class PhysicsComponent : Component
{
int pos;
public PhysicsComponent(int x) : base() { pos = x; }
}
public abstract class GenericSystem : List<Component>
{
public Type ComponentType;
public GenericSystem(Type componentType)
{ ComponentType = componentType; }
public void RegisterComponent(c)
{
Add(c);
c.SetSystem(this);
}
}
public class PhysicsSystem : GenericSystem
{
public PhysicsSystem() : base(typeof(PhysicsComponent)) { }
}
public static GenericEngine
{
List<GenericSystem> systems = new List<GenericSystem>();
//... Code here that adds some GenericSystems to the systems ...
public static void RegisterComponent(Component c)
{
foreach(GenericSystem aSystem in systems)
{
Type t = aSystem.ComponentType;
//PROBLEM IS HERE
t c_as_t = c as t;
//
if ( c_as_t != null)
aSystem.RegisterComponent(c);
}
}
}
Я получаю сообщение об ошибке: «Не удалось найти тип или пространство имен 't'».
Я хочу, чтобы у каждого GenericSystem
был тип Component
, который он хочет зарегистрировать для него. Таким образом, все, что регистрирует новый Component c
, просто вызывает GenericEngine.RegisterComponent(c)
, и все системы, заинтересованные в этом типе компонента, регистрируют его.
В идеале я бы хотел, чтобы код был больше похож на:
//where T must be a child of Component
public abstract class GenericSystem<T> : List<Component> { /... }
public class PhysicsSystem : GenericSystem<PhysicsComponent>
Я подозреваю, что это не очень сложный вопрос, и мне что-то не хватает о том, как C # работает с типами (или, что еще более неприятно, с универсальными шаблонами в целом), поэтому, если это простой вопрос, пожалуйста, просто укажите мне в направлении некоторого чтения материал. Заранее спасибо!
2 ответа
Объявления локальных переменных и "as" не работают. «t» - это выражение, которое во время выполнения оценивает ссылку на объект, представляющий тип . Локальный decl и as ожидают фрагмента программы, который во время компиляции называет тип .
Вы пытаетесь положить торт на полку книг с рецептами тортов; Хотя торты и книги рецептов пирожных тесно связаны, это не одно и то же.
Если вы хотите определить, имеет ли во время выполнения объект c тип, описанный объектом t, вы можете вызвать GetType для c и определить, являются ли эти два типа (1) равными, если вы требуете идентичность, или (2 ) совместимы, если вам просто требуется, чтобы один был совместим с другим.
В идеале я бы хотел, чтобы код был больше похож на:
//where T must be a child of Component
public abstract class GenericSystem<T> : List<Component>
Хорошо, тогда скажи, что:
public abstract class GenericSystem<T> : List<Component> where T : Component
Глядя на ваш дизайн, все остальное кажется подозрительным. Является ли универсальная система на самом деле своего рода списком компонентов или это, помимо прочего, содержит список компонентов? Используйте вывод, чтобы выразить «это своего рода» отношения. Используйте сдерживание, чтобы выразить «контейнерные» отношения. Автомобиль - это не список колес; автомобиль имеет список колес.
Сначала ты пишешь
if ((c as T) != null)
Что проще
if (c is T)
Затем, как указывает Эрик, этим операторам нужны типы, а не переменные, содержащие метаданные типа. Вам понадобится отражение, например:
if (t.IsAssignableFrom(c.GetType()))
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.