Я создаю вспомогательную функцию для сопоставления свойств объекта с объектом, который знает, к какому компоненту пользовательского интерфейса привязан свойство и как преобразовать его значения взад и вперед.Как использовать карту общих преобразователей в C#
Теперь мне нужна сама карта, чтобы отобразить имена свойств (типа String) в их ModelFieldItems, которые содержат общий конвертер (например, StringToBoolConverter). Но из-за отсутствия оператора <?>
я привык к Java, я не могу просто написать private Dictionary<String, ModelFieldItem> items = new Dictionary<String, ModelFieldItem<?,?>>();
, где ModelFieldItem содержит информацию о типе и самом преобразователе.
В результате мне нужно добавить определенные типы, если я хочу добавить ModelFieldItem к карте, но они различаются по типу. Я уже пытался использовать dynamic
или object
как параметры типа, но рано или поздно я дойду до точки, где она не работает.
Используя трюк из C# - Multiple generic types in one list я получил компилятор счастливым, но мне нужен был приведение типа доступ к моему логику преобразования, которые привели меня к следующему условию
if (item is ModelFieldItem<dynamic, dynamic>)
{
ModelFieldItem<dynamic, dynamic> dynamicItem = (ModelFieldItem<dynamic, dynamic>)item;
Который всегда решает для false
.
EDIT
Метод, который запускает преобразование, не знает, какие типы для преобразования, которые желательно. Мы используем цикл для итерации по свойствам и запуска их соответствующих преобразователей. Таким образом, кастинг в точке преобразования не может быть выполнен с помощью разных типов, потому что мы не можем их знать.
Наши преобразователи так же легко, как они могут быть, наследуя из следующего abstract class
public abstract class TypedConverter<A, B>
{
public abstract B convertFrom(A value);
public abstract A convertTo(B value);
}
Как упоминалось ранее, я из Java фона, так что я хочу, чтобы достичь выглядит примерно так следующее в Java
private Map<String, ModelFieldItem<?,?>> converters = new HashMap<>();
, и я хотел бы использовать его примерно как
converters.put("key", new Converter<String, Boolean>());
Как я могу достичь этого в C#?
Вы используете отражение для задания свойств на другой модели (через SetValue)? Отражение обычно работает с 'object', поэтому безопасность типа не покупает ничего. Тем не менее, вы можете использовать не-общий «ModelFieldItem» с базовым 'Func
Кроме того, взгляните на 'Convert.ChangeType' как альтернативу указанию конвертера для каждого свойства - или, по крайней мере, в качестве реализации по умолчанию. Вы также можете проверить Automapper, который специализируется на свойствах сопоставления. –
@TravisParks: спасибо за ваши комментарии. Нам нужна безопасность типа в нашем конвертере: a) сделать реализацию более ясной и b) установить правильный тип на модели, а при отражении нам все равно нужно установить правильный тип, или я не ошибаюсь. Идея для использования делегата хороша, я попробую. – Phe0nix