#c# #generics #casting
Вопрос:
У меня есть следующий класс:
public class Impactablelt;Tgt; : where T : Spawnablelt;Tgt; { protected T spawnable = Spawnablelt;Tgt;.Instance; void DoSomethingIndependentOfT(){} }
Причина, по которой я это реализовал, заключается в том, что Spawnable-это ленивый расширяемый синглтон. В Impactable у меня, конечно , есть методы, которые используют spawnable
, но также и методы, которые я не хотел бы использовать извне путем приведения.
public sealed class EnemySpawnable : Spawnablelt;EnemySpawnablegt; { } public class MyEnemyA : Impactablelt;EnemySpawnablegt; { } MyEnemyA enemy = new MyEnemyA(); Impactable x = enemy; x.DoSomethingIndependentOfT();
Возможно ли добиться такого приведения в C# или мне придется перепроектировать свой код?
Комментарии:
1. По сути, вы уже сделали это в своем примере кода. Определите базовый класс
Impactable
Impactablelt;Tgt;
, из которого он происходит, и поместите туда независимые материалы.2. Это похищение-очевидное решение, не так ли xD .. Тем не менее, я хочу узнать, в целом, возможен ли такой кастинг
Ответ №1:
Нет, это не так. Ограничение аргумента типа на Impactable
( where
) предотвращает это. Но необходимый рефакторинг является нетривиальным и тривиальным. Решение состоит в том, чтобы продвинуть независимые от типа методы в базовый класс, который не требует специализации, например:
public class Spawnablelt;Tgt; { public static T Instance; } public class Impactable { internal void DoSomethingIndependentOfT() { } } public class Impactablelt;Tgt; : Impactable where T : Spawnablelt;Tgt; { protected T spawnable = Spawnablelt;Tgt;.Instance; } public sealed class EnemySpawnable : Spawnablelt;EnemySpawnablegt; { } public class MyEnemyA : Impactablelt;EnemySpawnablegt; { } public class Program { public static void Main() { MyEnemyA enemy = new MyEnemyA(); Impactable x = enemy; x.DoSomethingIndependentOfT(); } }
Даже если то, что вы намеревались, было бы возможно (или стало возможным в будущих версиях C#), все равно намного проще сделать это таким образом, потому что он самостоятельно документирует намерение (методы, которые не используют универсальные, не должны находиться в контейнере с ограниченным типом).
Комментарии:
1. Это блестящее и простое решение, которое отлично подходит для моей конкретной проблемы в Unity, большое спасибо