Вы, вероятно, не должны хранить экземпляры ваших типов в списке.Вместо этого вы можете хранить типы.Они могут использоваться для создания экземпляров:
public static class DataTypes
{
static ReadOnlyCollection<Type> AvailableTypes;
static DataTypes()
{
List<Type> Types = new List<Type>();
Types.Add(typeof(MyTypeA));
Types.Add(typeof(MyTypeB));
AvailableTypes = new ReadOnlyCollection<MyDataType>(Type);
}
}
Вы можете использовать Activator.CreateInstance
для создания конкретного экземпляра:
Object myType = Activator.CreateInstance(AvailableTypes[0]);
Если ваши типы не имеют общий базовый тип, вы не можете уменьшитьрезультат и Object
не так полезны.
Также использование термина type в вашем коде делает мой пример немного запутанным, так как я предлагаю вам хранить типы чего-то под названием type .
Вы можете подумать о создании и атрибуте, который затем можете применить к MyTypeA
, MyTypeB
и т. Д. Затем вы можете построить AvailableTypes
с использованием отражения, и список всегда будетбыть в курсе своего кода.Например, если вы добавите MyTypeC
и используете атрибут, он будет автоматически добавлен в список.
Вы также можете добавить свойство отображаемой строки к атрибуту и использовать его для отображения в поле со списком.Если вы хотите сделать это, вы должны сохранить небольшой объект, объединяющий тип и отображаемую строку в AvailableTypes
.
Вот пример.Использование общих слов, таких как type и data , может сбить с толку, поэтому для выбора случайного имени я просто использую foo .Очевидно, вы должны использовать более описательное имя.
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
sealed class FooAttribute : Attribute {
public FooAttribute(String displayName) {
DisplayName = displayName;
}
public String DisplayName { get; private set; }
}
Вы можете украсить свои классы, используя этот атрибут:
[Foo("Type A")]
class MyTypeA { ... }
[Foo("Type B")]
class MyTypeB { ... }
Для комбинированного списка вам нужен список фабричных объектов с хорошим ToString
реализация (этот класс можно улучшить, добавив некоторую обработку ошибок, которую я оставил для экономии места):
class FooFactory {
readonly Type type;
public FooFactory(Type type) {
this.type = type;
DisplayName = ((FooAttribute) Attribute.GetCustomAttribute(
type,
typeof(FooAttribute))
).DisplayName;
}
public String DisplayName { get; private set; }
public Object CreateFoo() {
return Activator.CreateInstance(this.type);
}
public override String ToString() {
return DisplayName;
}
}
Возвращение Object
из CreateFoo
не очень полезно, но этоотдельная проблема.
Вы можете создать этот список во время выполнения:
var factories = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(t => Attribute.IsDefined(t, typeof(FooAttribute)))
.Select(t => new FooFactory(t));