实例化对象时使用“动态”与基本类型的区别

时间:2013-09-11 23:55:33

标签: c# asp.net-mvc asp.net-mvc-4 factory

我有点困惑的是,当在运行时直到此对象的类型未知时创建新对象时,最佳方法是什么。假设我有一个名为Store的基类,方法如下:

public class Store
{
   public Store()
   {
     Inventory = new List<Inventory>()
   }

   public string Title { get; set;} 
   public ICollection<Inventory> Inventory { get; set; }
}

现在假设我有另一个继承自Store类的类。我们称之为PetStore。在PetStore中,我定义了一个构造函数,只要StoreFactory创建一个对象,就会调用它:

的PetStore

public PetStore(Store store) : base(store)
{
    Title = ((PetStore)store).Title;
}

使用StoreFactory和反射来实例化对象:

public static Store FromTemplate(Store store)
{       
    Type type = Type.GetType(store.StoreType.ClassName);
    Store newstore = Activator.CreateInstance(type, store) as Store;
    return newstore;
}

现在回到问题的核心;通过执行以下操作实例化对象有什么区别:

Store newStore = StoreFactory.FromTemplate(existingPetStore);

dynamic newStore = StoreFactory.FromTemplate(existingPetStore);

我不确定我是否正确地写了这个问题。这可能有点令人困惑,如果是这样,我道歉。但是,我希望了解MVC如何区分这两者并最终,这是在这种情况下使用的最佳方法。

2 个答案:

答案 0 :(得分:2)

ASP MVC没有区分这两者,它是C#编译器。来自MSDN

  

动态类型使其发生的操作可以绕过编译时类型检查。相反,这些操作在运行时解决。

     

...

     

在大多数情况下,类型动态的行为类似于对象。但是,包含dynamic类型表达式的操作不会被编译器解析或进行类型检查。编译器将有关操作的信息打包在一起,该信息稍后用于评估运行时的操作。作为过程的一部分,dynamic类型的变量被编译为object类型的变量。因此,类型dynamic仅在编译时存在,而不是在运行时存在。

基本上这意味着你可以做这样的事情:

dynamic store = new Store();
store = 1;
store = "string";
store = new List<Store>();

虽然它可以在您的商店示例中使用,但您可以通过给自己偶然分配不同类型的值来增加错误的机会。然后,当你去使用它时,你会得到一个例外。您不仅可以更容易地遇到问题,而且还没有必要。

使用基类实例化类型是更好的选择。

Store newStore = StoreFactory.FromTemplate(existingPetStore);
但是,我很困惑,为什么你在工厂里使用反射。这对我来说似乎是一种浪费...为什么不返回一个new PetStore,其中包含您想要设置的所有属性?或者,如果在运行时未知existingPetStore,为什么不让对象实现ICloneable并执行MemberwiseClone或其他操作?在我看来,反思似乎是一个奇怪的选择...

答案 1 :(得分:1)

反对它的一个论点是你在使用它时没有编译时类型安全性。有些是编译时错误,而是表现为运行时错误。

除此之外,我认为除了公共语言运行时之外,还需要您的代码使用动态语言运行时。您的代码也会在运行时执行许多检查,这将对性能产生负面影响。

要阅读有关DLR的更多信息,请查看msdn上的这篇文章; http://msdn.microsoft.com/en-us/library/dd233052.aspx