我有点困惑的是,当在运行时直到此对象的类型未知时创建新对象时,最佳方法是什么。假设我有一个名为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如何区分这两者并最终,这是在这种情况下使用的最佳方法。
答案 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