1

当这个对象的类型在运行时未知时,当创建一个新对象时,最好的方法是什么,我有点困惑。假设我有一个名为 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创建对象时都会调用它:

宠物店

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 如何区分这两者,最终,这是在这种情况下使用的最佳方法。

4

2 回答 2

2

ASP MVC 不区分这两者,它是 C# 编译器。从MSDN

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

...

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

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

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

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

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

Store newStore = StoreFactory.FromTemplate(existingPetStore);

不过,我很困惑,为什么您在工厂中使用反射。这对我来说似乎是一种浪费......为什么不返回一个new PetStore你想要设置的所有属性集?或者,如果existingPetStore在运行时不知道,为什么不让你的对象实现ICloneable并做MemberwiseClone一些事情呢?在我看来,反思似乎是一个奇怪的选择......

于 2013-09-12T00:53:12.040 回答
1

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

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

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

于 2013-09-12T17:05:10.470 回答