私は一般的なモデルを持っています:
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 クラスの使用を防ぐために行っていることと関係があると思います。しかし、それに関するドキュメントは見つかりません。