Вот дословный порт:
// Untested code
public class Factory
{
private static int _id = 0;
// Use Dictionary to store the mapping from int to Type
// instead of ActionScript "classLib = new Array();"
private static readonly IDictionary<int, Type> _typeMappings = new Dictionary<int, Type>();
public Factory()
{
}
public static int AddClassLink(Type type)
{
// To insure uniqueness, increment a static local id and use that
int localId = ++_id;
// Store the Type of the class to instantiate against the integer ID
// Similar to ActionScript "classLib.push(logicClass); "
_typeMappings[localId] = type; // Set in dictionary
return localId;
}
pubilc static FactoryObject CreateClassFromId(int id, DataObject constructorDataObject)
{
// Get the class type by integer Id.
// You can also use _typeMappings.Contains and _typeMappings.TryGetValue() to
// add some checking first
var type = _typeMappings[id];
// This is equivalent to new DerivedFactoryObject() where Type
// is the runtime Type of the class registered in AddClassLink
var obj = (FactoryObject)Activator.CreateInstance(type);
// Initialise and return
obj.Init(constructorDataObject);
return obj;
}
}
В этом примере я использовал Dictionary<TKey, TValue
вместо Array, чтобы при удалении из словаря типов не возвращался идентификатор, который вы возвращаете. В приведенном выше примере, пока AddClassLink не вызывается в нескольких потоках, вы будете каждый раз получать уникальный идентификатор, даже если классы отменены.
Что касается создания экземпляра типа, используйте перегрузку System.Type, равную Activator.CreateInstance
. Это может создать объект только по типу времени выполнения.
Что касается использования этого класса, если у вас есть класс, который вы хотите зарегистрировать в нем, вы бы использовали эту запись
var myFactory = new Factory();
int id = myFactory.AddClassLink(typeof(SomeClassIWantInstantiated))
// ...
SomeClassIWantInstantiated instance = myFactory.CreateClassFromId(id, new DataObject())
Вышеуказанное должно работать (Отказ от ответственности: не проверено!) и должно быть точным портом вашего кода ActionScript. * Это не значит, что это хорошая идея или лучшие практики! *
Я рекомендую взглянуть на контейнеры Dependency Injection и взглянуть на Factory Pattern в .NET , поскольку сила отражения, типизация во время выполнения и т. Д. Позволяют реализовать этот шаблон элегантно и надежно в C #. В частности, DI Containers позволит вам зарегистрироваться и разрешить класс следующим образом
var myFactory = new DependencyInjectionContainerTm();
myFactory.Register(typeof(SomeClassIWantInstantiated))
// ...
SomeClassIWantInstantiated instance = myFactory.Resolve<SomeClassIWantInstantiated>();
Основное использование контейнера заключается в том, чтобы связать зависимости и разрешить инжекцию конструктора в качестве интерфейсов, что приводит к хорошо изолированному, легко тестируемому коду, однако это по сути фабрика типизированных объектов.