Может быть, язык изменился с момента публикации, но это работает для меня. Это пример того, где я хотел скрыть инициализатор, чтобы контролировать время жизни объекта и выполнять постобработку. В этом случае я хотел отслеживать и отправлять аналитику, основываясь на конфигурации звонящего.
private protocol Reportable {
init()
var people:[String:AnyObject] { get }
var track:[String:AnyObject] { get }
}
public class Analytics {
public final class Alpha: Reportable {
var thingOne: String?
var thingTwo: String?
private init() {}
private var people:[String:AnyObject] { return [:] }
private var track:[String:AnyObject] { return [:] }
}
public final class Bravo: Reportable {
var thingOne: String?
var thingTwo: String?
private init() {}
private var people:[String:AnyObject] { return [:] }
private var track:[String:AnyObject] { return [:] }
}
public static func alpha(configure:Alpha -> ()) {
return report(configure)
}
public static func bravo(configure:Bravo -> ()) {
return report(configure)
}
private static func report<T:Reportable>(configure:T -> ()) {
let event = T()
configure(event)
Analytics.doSomething()
}
static func doSomething() {
}
}
// separate file
func clientCode() {
Analytics.alpha { event in
event.track // error
event.thingOne = "foo"
event.thingTwo = "bar" }
Analytics.bravo { event in
event.thingOne = "foo"
event.thingTwo = "bar" }
}
Вы можете использовать этот метод, чтобы получить то, что хотите, хотя
public static class Animal {
public enum Dog {
BullDog,
GreyHound,
Huskey
}
public enum Cat {
Tabby,
Bombbay
}
}
Я бы, вероятно, использовал комбинацию пронумерованных битовых полей и методов расширения для достижения этого. Например:
public enum Animal
{
None = 0x00000000,
AnimalTypeMask = 0xFFFF0000,
Dog = 0x00010000,
Cat = 0x00020000,
Alsation = Dog | 0x00000001,
Greyhound = Dog | 0x00000002,
Siamese = Cat | 0x00000001
}
public static class AnimalExtensions
{
public bool IsAKindOf(this Animal animal, Animal type)
{
return (((int)animal) & AnimalTypeMask) == (int)type);
}
}
Обновление
В .NET 4 можно использовать метод Enum.HasFlag
, а не развертывать собственное расширение.
Просто нет, не может
Я рекомендую вам определить все значения в перечислении Animal
. Есть ли причина, по которой вам нужна именно эта структура?
Я не думаю, что это работает так.
Перечисления должны быть простым набором параллельных значений.
Вы можете выразить эту связь с помощью наследования.
См. Следующие вопросы:
Получение значений статических полей типа с использованием отражения
Сохранение строковых значений как констант таким же образом, как и в Enum
Вопросы охватывают построение базовой строки enum, но я реализую свои ответы с помощью интерфейса ICustomEnum
, который может помочь вам в этой ситуации.
Возможно, этого будет достаточно?
class A
{
public const int Foo = 0;
public const int Bar = 1;
}
class B : A
{
public const int Baz = 2;
}