Надеюсь, вы можете дать мне руку на это. Это уже беспокоило меня уже довольно давно. и я не нахожу окончательных ответов в Интернете. У меня есть простая иерархия классов: BaseClass с ClassA, ClassB и DefaultClass, полученными из него. У всех их есть конструктор типа ClassA (Input input): base (input) ... все очень просто. Теперь у меня есть следующий автокрепежДанный ключ отсутствует в словаре на Activator.CreateInstance
namespace mynamespace
{
public class Factory
{
public static Dictionary<string, Type> Map =
new Dictionary<string, Type>
{
{"ClassA", typeof(ClassA)},
{"ClassB", typeof(ClassB)}
};
public static BaseClass Create(Input input)
{
Type constructor;
try
{
constructor = Map[input.ClassType];
}
catch (KeyNotFoundException)
{
constructor = typeof(DefaultClass);
}
return (BaseClass) Activator.CreateInstance(constructor, input);
}
}
}
Как вы видите, член .ClassType объекта ввода определяет, какой класс конкретизируется. Этот тип конструкции работает для простого вызова, такого как
var myClass = Factory.Create(input);
в моем автономном приложении. Теперь у меня должно быть приложение, запущенное на сервере, и вызов метода Create получает от клиента сериализованный входной объект. Я бы сказал, что это единственная разница между приложением, которое работает, и тем, которое этого не делает. Теперь, вход что-то вдоль линий
[DataContract]
public class Input
{
[DataMember] public string ClassType;
[DataMember] public string member1;
}
Тогда как до того, как не было таких DataContract или DataMember аннотаций. Итак, теперь код разбился в строке Activator.CreateInstance с исключением «данный ключ отсутствовал в словаре». У вас есть какая-то подсказка, почему это может быть? Единственное отличие - это сериализованный объект в конструкторе.
Большое спасибо и приветствуем.
Вы должны использовать Dictionary.TryGetValue вместо того, чтобы ловить KeyNotFoundException. Исключения очень дороги. –
Не могли бы вы отправить трассировку стека исключения? – svick
Я не вижу, как Activator.CreateInstance выдаст такое исключение. Это может быть брошено только на конструктор строк = Map [input.ClassType] – Bond