Я не уверен, почему (большинство) ответов упоминают рефлексию - хороший старый полиморфизм прекрасно подходит для этого. Получить имя типа среды выполнения просто - просто this.GetType().Name
.
Единственная сложная часть - поддержка уникальных счетчиков для каждого класса. Это было обсуждено ранее на SO - но я не могу найти ссылку ATM. Но, суть в том, что вы можете (ab) использовать дженерики или поддерживать Dictionary<Type, int>
для отслеживания.
Универсальная версия работает, потому что каждый параметр другого типа создает свой универсальный класс - поэтому у каждого из них разные статические счетчики:
abstract class Command<T> where T : Command<T> {
private static int counter = 1;
private static object syncLock = new object();
protected Command() {
lock (syncLock) {
_name = this.GetType().Name + counter++.ToString();
}
}
public string Name { get { return _name; } }
private string _name;
}
class Blur : Command<Blur> { }
class Sharpen : Command<Sharpen> { }
Нет необходимости переопределять что-либо в производных классах, но вы должны убедиться, что ваш унаследованный Command<T>
правильный - или вы будете использовать счетчики. Я также использовал блокировку для синхронизации доступа к счетчику - при условии, что вы будете создавать экземпляры из более чем одного потока.
Если вам не нравится универсальная версия, Dictionary<Type, int>
работает так же хорошо.
abstract class Command {
private static Dictionary<Type, int> counter = new Dictionary<Type, int>();
private static object syncLock = new object();
protected Command() {
Type t = this.GetType();
lock (syncLock) {
if (!counter.ContainsKey(t)) {
counter.Add(t, 0);
}
_name = t.Name + counter[t]++.ToString();
}
}
public string Name { get { return _name; } }
private string _name;
}
class Blur : Command { }
class Sharpen : Command { }
Поскольку вы будете создавать "миллионы" каждого из них, я, вероятно, профилирую оба и проверю использование памяти. Мне не особенно важен общий подход - поскольку его легко испортить и передать неверный параметр типа, - но я подозреваю, что использование памяти немного лучше. Кроме того, если вы собираетесь создать> int.MaxValue
, вам придется беспокоиться о переполнении.
Несмотря на это, я не уверен, почему бы вам не просто поддерживать адресуемую коллекцию индекса и ссылаться на нее по индексу - как Blur[0]
?