2

我有一个通用模型:

public abstract class MyModel<T> 
    where T: MyBase, new()
{ ... }

我有一个特定的模型,其中 Foo 从 MyBase 继承:

public class MySpecificModel : MyModel<Foo>
{ ... }

在我的 Razor 模板中,我想实例化 MySpecificModel 的一个实例:

@{
    var test = new MySpecificModel();
}

如果 MyBase 继承自 System.Windows.DependencyObject(因为它恰好是我需要重用的 WPF ViewModel 类),我会在编译 Razor 模板时收到异常,说我缺少对 WindowsBase.dll 的引用,即使我的项目中有这个参考。我尝试将 @using System.Windows 添加到我的模板中,但 Razor 根本无法识别命名空间。

为了解决这个问题,我将代码更改如下:

public abstract class MyModel 
{
    protected abstract MyBase myBase { get; }
    ... 
}

public class MySpecificModel : MyModel
{
    private Foo _myBase;
    protected override MyBase myBase
    {
        get
        {
            if (_myBase == null)
                _myBase = new Foo();
            return _myBase;
        }
    }
    ... 
}

在 MyModel 中,我必须将任何“new T()”更改为“myBase”才能访问 Foo 对象。这种方法非常有效,但对于 MySpecificModel 类来说工作量要大得多,我将为 MyBase 的不同子类提供许多变体。

那么,为什么第一种方法失败而第二种方法成功呢?这不仅仅是泛型的使用,因为如果 MyBase 不从 WindowsBase 类继承,那就没有问题。我认为这与构造 Foo 对象的位置有关,以及 Razor 正在做的事情以防止使用任何 WPF 类。但我找不到任何关于此的文档。

4

1 回答 1

1

ASP.NET 从.aspx/ .ascx/ .master/ .cshtml 文件生成一个新的匿名程序集,然后引用您的 Web 应用程序的程序集,生成的类存储在ASP.命名空间中。此程序集是在运行时向您的 Web 应用程序发出第一个请求时生成的。

这个新程序集仅额外引用了一些其他程序集(System.Web.dll等),而不是System.Windows.xxx您注意到的程序集。

因为 ASP.NET 正在生成一个基于公开类型的新程序集,System.Windows所以它需要直接引用该程序集,而它不会 - 而当它使用派生自 System.Windows 类型的类型的子类型时(即您的工作示例)它之所以有效,是因为它不直接与 System.Windows 交互。

于 2012-09-18T23:42:54.607 回答