#c# #types
#c# #типы
Вопрос:
Я использую внешнюю библиотеку C #, которая использует generics для своих процессов. Но я хочу использовать его в цикле, который находится во внешнем классе. Моя проблема в том, что я не могу передавать типы между классами.
Вот пример:
Я использую класс SettingsXmlReader для чтения некоторых частей XML-файла. Эти части указаны в конкретных классах:
SettingsXmlReader settingsXmlReader = new SettingsXmlReader(settingsXmlPath);
settingsXmlReader.AddContainer(typeof(ReleasePathContainer));
settingsXmlReader.AddContainer(typeof(HistoryPathContainer));
(...)
Итак, я передал свои конкретные типы в объект settingsXmlReader, но теперь я не могу использовать эти типы следующим способом (поскольку этого требует внешняя библиотека):
foreach (Type aContainer in containers)
{
XmlContainerInitializer<aContainer> containerInitializer = new XmlContainerInitializer<aContainer>();
IBaseContainer container = containerInitializer.InitializeXmlContainer(settingsXmlFile);
}
'aContainer' is a variable but is used like a type
Я также попробовал следующий режим:
SettingsXmlReader settingsXmlReader = new SettingsXmlReader(settingsXmlPath);
settingsXmlReader.AddContainer<ReleasePathContainer>();
settingsXmlReader.AddContainer<HistoryPathContainer>();
Но в этом случае я не знаю, как его сохранить или использовать:
private IList<T> containers;
public void AddContainer<T>()
{
containers.Add<T>();
}
Комментарии:
1. У вас уже есть код, который это делает
settingsXmlReader.AddContainer(typeof(ReleasePathContainer))
. Разве вы не можете просто сделатьsettingsXmlReader.AddContainer(type)
?2. Если я использую его следующим образом:
settingsXmlReader.AddContainer(ReleasePathContainer);
я получил следующую ошибку от IntelliSense: ReleasePathContainer — это тип, который недопустим в данном контексте.3. Как и в вашем цикле
foreach (Type aContainer in containers)
. Не можете ли вы тогда сделатьsettingsXmlReader.AddContainer(aContainer);
?4.
typeof(ReleasePathContainer)
возвращает вамType
объект, который представляетReleasePathContainer
тип. Вы можете сделатьType type = typeof(ReleasePathContainer); settingsXmlReader.AddContainer(type)
, и он делает то же самое, что иsettingsXmlReader.AddContainer(typeof(ReleasePathContainer))
5. Вы не можете. Вы можете перейти от generics к
Type
object (Type type = typeof(T)
) , но вы не можете вернуться другим путем, не используя отражение. Дженерики являются частью системы строгих типов C #;Type
объекты — нет.
Ответ №1:
Если вам действительно нужно использовать этот цикл «AContainer», вы можете избежать ошибки переменной против типа, используя MakeGenericType , что-то вроде этого:
Type[] typeArgs = new Type[] { aContainer };
Type genericType = typeof(XmlContainerInitializer<>);
Type specificType = genericListType.MakeGenericType(typeArgs);
// This gets you a XmlContainerInitializer of the right type
var containerInitializer = Activator.CreateInstance(specificType);
// You can then try using it dynamically
dynamic d = containerInitalizer;
IBaseContainer container = (IBaseContainer)d.InitializeXmlContainer(settingsXmlFile);
// Or, if XmlContainerInitializer supports some base interface IContainerInitializer ...
var i = (IContainerInitializer)containerInitializer;
IBaseContainer container = i.InitializeXmlContainer(settingsXmlFile);
Комментарии:
1. Спасибо за вашу помощь, теперь он работает нормально и динамически. Это то, что я хотел. 🙂