Класс C# с подпунктами
Скажем, я хочу иметь основной класс со многими подклассами, все подклассы с одинаковыми свойствами / методами, и мне нужно получить к ним доступ во многих других частях кода.
Пример: Основной класс: Страна
Подклассы / Предметы: Германия, Нидерланды, Великобритания, Франция,...
Затем определяем отдельные свойства для каждой страны, такие как население, единицы,...
Так что позже в коде я могу получить к нему доступ, как
if (Country.France.Units < Country.Germany.Units)
Console.WriteLine("foo");
Изменить: Спасибо за ответы всех, решение CodeCaster идеально подходит для моей цели. Другие тоже правы, разбор словаря по строковым значениям - это просто меньше работы...
4 ответа
Вы не хотите этого делать, потому что тогда для каждой добавленной страны вам придется перекомпилировать, то есть вы не можете автоматически связывать данные, загруженные из внешнего источника данных, со статически типизированным свойством.
Вместо этого используйте словарь:
var countries = new Dictionary<string, Country>();
// ...
if (countries["France"].Units < ...)
Специально для решения текущей задачи вы можете создать класс Country с приватным конструктором и статическими свойствами для каждой страны.
public class Country
{
private Country()
{
}
public int Population {get; private set;}
// Static members
public static Country USA {get; private set;}
public static Country Italy {get; private set;}
static Country()
{
USA = new Country { Population = 100000 };
Italy = new Country { Population = 50000 };
}
}
Вы можете получить к нему доступ с помощью следующего кода
Country.USA.Population < Country.Italy.Population
То, что вы хотите, звучит очень похоже на Color
структура. Он имеет большой предопределенный набор классов, но по-прежнему допускает "пользовательские" цвета.
В отличие от Color
, тем не мение, Country
имеет свойства, которые могут изменяться с течением времени, и может выиграть от наличия внешнего источника данных, который можно обновлять. Существует также ограниченное число стран, поэтому вы можете оптимизировать память, не используя тысячи экземпляров "France".
Один образец, который соответствовал бы этому, является Flyweight. Вы можете свести к минимуму количество объектов, плавающих вокруг, используя фабричный метод, но при этом разрешить легкий доступ к заранее определенному набору стран:
public class Country
{
// properties of a Country:
public int Population {get; private set;}
public string Units {get; private set;}
// etc.
// Factory method/fields follows
// storage of created countries
private static Dictionary<string, Country> _Countries = new Dictionary<string,Country>();
public static Country GetCountry(string name)
{
Country country;
if(_Countries.TryGetValue(name, out country))
return country;
//else
country = new Country();
// load data from external source
_Countries[name] = country;
return country;
}
public static Country France { get {return GetCountry("France");} }
public static Country Germany { get {return GetCountry("Germany");} }
}
Некоторые оговорки с дизайном как есть:
- Это не потокобезопасно. Вам нужно будет добавить правильную безопасность потока.
- Страны не вечны - что бы вы сделали, если бы заранее определенной страны больше не существовало?
- В идеале фабрика должна быть отдельным классом, чтобы вы могли
Country
класс с завода, но я думаюCountry.France
выглядит лучше чемCountryFactory.France
Если вам не нравится разбор строк словаря, и ваш список относительно мал, вы можете просто сделать что-то вроде этого:
List<Country> counties = new List<Country>();
countries.Add(France as Country);
countries.Add(Germany as Country);
...
var France = countries.FirstOrDefault(t => t is France);