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;
        }
    }
    ... 
}

Foo オブジェクトにアクセスするには、MyModel 内で「new T()」を「myBase」に変更する必要があります。このアプローチは完全に機能しますが、MySpecificModel クラスの場合はより多くの作業が必要になります。このクラスには、MyBase のさまざまなサブクラス用にさまざまなバリエーションがあります。

では、なぜ最初のアプローチは失敗し、2 番目のアプローチは成功するのでしょうか? MyBase が WindowsBase クラスから継承されていない場合、問題はないため、ジェネリックの使用だけではありません。Foo オブジェクトが構築されている場所と、Razor が WPF クラスの使用を防ぐために行っていることと関係があると思います。しかし、それに関するドキュメントは見つかりません。

4

1 に答える 1

1

ASP.NET は、Web アプリケーションのアセンブリを参照する.aspx/ .ascx/ .master/ .cshtml ファイルから新しい匿名アセンブリを生成し、生成されたクラスはASP.名前空間に格納されます。このアセンブリは、Web アプリケーションに対して最初の要求が行われたときに、実行時に生成されます。

この新しいアセンブリは、他のいくつかのアセンブリ (System.Web.dllなど) を追加で参照するだけで、お気付きのSystem.Windows.xxxアセンブリではありません。

ASP.NET は、公開された型に基づいて新しいアセンブリを生成しているためSystem.Windows、そのアセンブリを直接参照する必要がありますが、そうではありません。一方、型の子が System.Windows 型から派生した型 (つまり、実際の例) で動作する場合は、そうではありません。 System.Windows と直接インターフェイスしていないため、機能します。

于 2012-09-18T23:42:54.607 に答える