2012-06-22 106 views
4

我希望你能给我一个这方面的帮助。它已经困扰了我很长一段时间了。我在网上找不到确凿的答案。我有一个简单的类层次结构:带有ClassA,ClassB和DefaultClass的BaseClass派生自它。它们都有一个像ClassA(输入输入)一样的构造函数: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; 
} 

wheras之前它没有这样的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

太好了,所以,请将我的答案标记为已接受。 –

相关问题