1

Generic Task レイヤー (私のプロジェクトでは AppServ と呼ばれます) を作成して、汎用リポジトリとやり取りしようとしています。これはジェネリックへの私の最初のダイビングであり、ジェネリック クラス内にあるジェネリック メソッド パラメーターに値を渡す際に問題が発生しています。

Base App Services クラス (特定の app serv クラスによって継承され、Generic Repository を呼び出します):

public class BaseAppServ<T> : IBaseAppServ<T> where T : class, IEntity, IAuditStamps, ICompanyFacility, new()
{
    private Repository<T> _repository;
    private T _viewModel;
    private AuditStampsViewModel _auditStamps;

    public BaseAppServ(Repository<T> repository)
    {
        _repository = repository;
        _viewModel = new T();
        _auditStamps = new AuditStampsViewModel();
    }

これが私の特定のAppServクラスです(BaseAppServを継承します)

public class ManageItemsAppServ : BaseAppServ<ManageItemsAppServ>, IEntity, IAuditStamps, ICompanyFacility
    {

        public ManageItemsAppServ()
            : base(CallBaseConstructor())
            {

            }

            public static Repository<Item> CallBaseConstructor()
            {
                return new Repository<Item>(new InventoryMgmtContext());
            }

コンストラクターまたは ManageItemsAppServ、特に base(CallBaseConstructor()) 行に問題があります。次のエラーが発生します。

Argument 1: cannot convert from 'OTIS.Data.Repository<OTIS.domain.InventoryMgmt.Item>' to 'OTIS.Data.Repository<OTIS.AppServ.InventoryMgmt.ManageItemsAppServ>'

なぜこれが起こっているのかはわかっていると思います(BaseAppServ を継承するときに、タイプ ManageItemsAppServ の T を指定していて、それが BaseAppServ クラス全体に T のタイプを設定しているためです....そうですか?)

では、タイプ Respository を探しているコンストラクター呼び出しに対して T を再定義するにはどうすればよいでしょうか。

編集:したがって、 BaseAppServ クラスに2番目の汎用パラメーターを追加する必要があると思います(タイプリポジトリに制約する U に注意してください):

public class BaseAppServ<T, U> where U : Repository<U>, IBaseAppServ<T> where T : class, IEntity, IAuditStamps, ICompanyFacility, new()
    {
        private Repository<U> _repository;
        private T _viewModel;
        private AuditStampsViewModel _auditStamps;

        public BaseAppServ(Repository<U> repository)
        {
            _repository = repository;
            _viewModel = new T();
            _auditStamps = new AuditStampsViewModel();
        }

これは正しいパスのようですが、唯一のエラーは次のとおりです。

Inconsistent accessibility: constraint type 'OTIS.AppServ.IBaseAppServ<T>' is less accessible than 'OTIS.AppServ.BaseAppServ<T,U>'

これは、BaseAppServ クラス宣言の順序/構文と関係があります。それは何ですか?

4

1 に答える 1

1

aが期待されるRepository<Item>場所に as コンストラクター引数を渡そうとしています。Repository<ManageItemsAppServ>

ジェネリック クラスは共変または反変できないため、thisItemから継承しても有効な操作ではないことに注意してください。ManageItemsAppServ

したがって、要するに、正確な型を渡すか、共変のインターフェイスを使用するようにしてください (インターフェイスが共変であるかどうかは、そのメソッドに依存します)。

編集:

編集によると、おそらく次のようなものが必要です。

public class BaseAppServ<TModel, TItem>: IBaseAppServ<TModel>
            where TItem : class, IEntity 
            where TModel: ICompanyFacility, new()
{
    private Repository<TItem> _repository;
    private TModel _viewModel;
    private AuditStampsViewModel _auditStamps;

    public BaseAppServ(Repository<TItem> repository)
    {
        _repository = repository;
        _viewModel = new TModel();
        _auditStamps = new AuditStampsViewModel();
    }
于 2012-12-22T01:03:23.990 に答える