2012-06-22 3 views
4

Надеюсь, вы можете дать мне руку на это. Это уже беспокоило меня уже довольно давно. и я не нахожу окончательных ответов в Интернете. У меня есть простая иерархия классов: 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 с исключением «данный ключ отсутствовал в словаре». У вас есть какая-то подсказка, почему это может быть? Единственное отличие - это сериализованный объект в конструкторе.

Большое спасибо и приветствуем.

+2

Вы должны использовать Dictionary.TryGetValue вместо того, чтобы ловить KeyNotFoundException. Исключения очень дороги. –

+0

Не могли бы вы отправить трассировку стека исключения? – svick

+0

Я не вижу, как Activator.CreateInstance выдаст такое исключение. Это может быть брошено только на конструктор строк = Map [input.ClassType] – Bond

ответ

5

Приведенные ниже фрагменты кода должны работать нормально. Посмотрите на свои конструкторы ваших объектов. Я уверен, что исключение возникает где-то внутри их реализации.

И я полностью согласен с тем, что лучше использовать Dictionary.TryGetValue() вместо исключения исключения. Вот полезная ссылка, чтобы узнать исключения: Exception Handling.

+0

Вы Правильно. Это было в конструкторе. Привет. E – edd

+2

Отлично. Итак, отметьте мой ответ так, как принято тогда. –

Смежные вопросы