#c# #generics
#c# #обобщения
Вопрос:
Я довольно новичок в мире C # и приношу извинения, если название вопроса не совсем соответствует содержанию. Но теперь к моей Проблеме:
У меня есть следующая конструкция:
public interface IClass<TEnum>
{
Dictionary<TEnum, ISecondClass> dictionary { get; }
}
public abstract class ClassBase<TEnum> : IClass<TEnum>
{
public abstract Dictionary<TEnum, ISecondClass> dictionary { get; protected set; }
}
public class ConcreteClass : ClassBase<ConcreteClass.Concrete>
{
public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }
public enum Concrete : ulong
{
}
}
public class OtherClass : ClassBase<OtherClass.Other>
{
public override Dictionary<Concrete, ISecondClass> dictionary { get; protected set; }
public enum Other : ulong
{
}
}
Моя цель — создать экземпляры всех существующих конкретных классов на основе их перечислений, сохранить все экземпляры в словаре и позже вызвать некоторые методы для каждого объекта.
Я не уверен, возможно ли это вообще?
Я рад любому намеку на это!
Комментарии:
1. Вы хотите сказать, что словарь должен глобально отслеживать каждый экземпляр класса?
2. Здесь есть много вариантов. Это могло бы помочь, если бы вы показали нам, как должен выглядеть код, который «вызывает некоторые методы»
3. Кстати, я заметил, что словарь в OtherClass является
Dictionary<Concrete, ISecondClass>
. Должно ли это бытьDictionary<Other, ISecondClass>
?4. @justin да, вы правы. Я исправлю это. @conrad Хорошо, я сделаю это, как только вернусь к своей записной книжке. В данный момент я нахожусь на своем смартфоне
Ответ №1:
Если я понимаю, что вы пытаетесь сделать, это звучит как версия многотонного шаблона. Возможно, вам будет полезно изучить это.
Из примера многотонного кода Википедии:
class FooMultiton
{
private static readonly Dictionary<object, FooMultiton> _instances = new Dictionary<object, FooMultiton>();
private FooMultiton() {}
public static FooMultiton GetInstance(object key)
{
lock (_instances)
{
FooMultiton instance;
if (!_instances.TryGetValue(key, out instance))
{
instance = new FooMultiton();
_instances.Add(key, instance);
}
}
return instance;
}
}
Это не может быть вставлено непосредственно в ваш класс, но поскольку вы ищете подсказки, я думаю, это должно указать вам правильное направление.
Одно предостережение по поводу приведенного выше кода: метод GetInstance
изменит словарь, если key
не будет найден. Лично у меня префикс «Get» ассоциируется с методами, доступными только для чтения. Я бы либо переименовал GetInstance
, либо разделил его на два метода.
Однако я не совсем уверен, что вы подразумеваете под «созданием экземпляров всех существующих конкретных классов на основе их перечислений». Можете ли вы пояснить это?
Комментарии:
1. Спасибо за быстрый ответ, но это не совсем моя проблема. Я думаю, мне нужно опубликовать больше кода, чтобы описать все аспекты моей проблемы.
2. Мой вопрос и название выбраны не так удачно, поэтому ваш ответ наиболее близок к тому, что я ищу. К тому времени я разобрался, как вызывать методы самостоятельно.
Ответ №2:
Используйте Activator.CreateInstance()
для создания объектов конкретных классов и сохранения их в словаре.
Передайте свой string classname from Enum
и создайте объекты динамического класса. Сохраните их в Dictionary<Enum, ISecondClass>
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
or
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
При извлечении, основываясь на вашем ключе enum, вы знаете, какой тип представляет значение экземпляра.
Комментарии:
1. Да, это то, о чем я подумал. Но я хочу использовать один цикл для обработки всего, а затем я не могу ввести конкретный базовый класс, потому что все они реализуют другое перечисление, основанное на конкретном классе. Я попытаюсь перепостить некоторый код, я вижу, что то, что я опубликовал, не отражает всех аспектов моей проблемы. Но мне нужно сделать это, когда я не нахожусь на своем смартфоне. Я думаю, завтра.
Ответ №3:
Я не понимаю цели примера кода, но вы можете написать что-то вроде этого:
public interface IClass
{
void MethodToDynamicInvoke();
}
public abstract class ClassBase<T>
: IClass
{
private Dictionary<Type, List<IClass>> instances = new Dictionary<Type, List<IClass>>();
public ClassBase()
{
List<IClass> list;
if (!instances.TryGetValue(typeof(T), out list))
{
list = new List<IClass>();
instances.Add(typeof(T), list);
}
list.Add(this);
}
public abstract void MethodToDynamicInvoke();
public void InvokeMetodOnClassesWithSameEnum()
{
List<IClass> list;
if (instances.TryGetValue(EnumType, out list))
{
foreach (var instance in list)
{
instance.MethodToDynamicInvoke();
}
}
}
}
public class ConcreteClass
: ClassBase<ConcreteClass.Concrete>
{
public ConcreteClass()
: base()
{
}
public override void MethodToDynamicInvoke()
{
throw new NotImplementedException();
}
public enum Concrete : ulong
{
}
}
public class OtherClass : ClassBase<OtherClass.Other>
{
public OtherClass()
: base()
{
}
public override void MethodToDynamicInvoke()
{
throw new NotImplementedException();
}
public enum Other : ulong
{
}
}