1

ディクショナリとそれに含まれるアイテムを含むいくつかの汎用インターフェイスを作成しようとしています。現在、どちらも以下のコードのようになっています。

ご覧のとおり、ディクショナリをパントして、値をオブジェクトにしました。アイテムのように、TParentMOdel の共変キーと TModel の共変値を持つインターフェイスが理想的ですが、これまでのところそれを解決できませんでした (それが可能かどうかもわかりません)。

以下の最後の使用例で最後の項目を追加しようとするまで、私がしていることはうまくいくようです。GenderVm は本質的に ISateliteVm です

問題は Gender が Enum であるように思われますが、これは私には完全には理解できません。この場合の TParentModel は、Party のサブクラスである Person です。TParentModel が Person である他の項目を追加できるため、ここでは共分散が機能しているようです。

だからこそ、問題はジェンダーの価値にあるように思えます。それは列挙型であり、列挙型はオブジェクトですが、型制約システムは列挙型をサポートしていないと思います。

キャストなどの簡単な修正はありますか?A SatelliteMap を設計するためのより良い方法を見つけた人はいますか?

乾杯、
ベリル

アイテム

public interface ISatelliteVm<out TParentModel, out TModel> : ISatelliteVm
{
    TParentModel ParentModel { get; }
    TModel Model { get; }
}

辞書

public class SatelliteVmMap<TParentModel> : Dictionary<Type, ISatelliteVm<TParentModel, object>>, IEditableObject, IIsDirty
{

    public void Add(ISatelliteVm<TParentModel, object> item) {
        if (item == null)
            throw new ArgumentNullException("item");
        Add(item.GetType(), item);
    }
}

使用法 (SatelliteMap を含む抽象クラス)

public interface IHubViewModel<out TModel> where TModel : Entity
{

    public void AddSatelliteVm(ISatelliteVm<TModel, object> vm) {
        if (_satelliteVmMap == null) {
            _satelliteVmMap = new SatelliteVmMap<TModel>();
        }
        if (_satelliteVmMap.ContainsKey(vm)) return;

         _satelliteVmMap.Add(vm);
    }
}

使用法 (ISatelliteVm の複数のエントリを含むサブクラス)

    public abstract class PartyDetailVm : HubViewModel<Party>
{
    ...

    public LifespanVm LifespanVm { get { return GetSatelliteVm<LifespanVm>(); } }
    public AvatarVm AvatarVm { get { return GetSatelliteVm<AvatarVm>(); } }
    public TelecomNumberPcmShellVm TelecomNumberPcmShellVm { get { return GetSatelliteVm<TelecomNumberPcmShellVm>(); } }

    ...
}

使用法 (ISatelliteVm の複数のエントリを含むサブクラス)

public class PersonDetailVm : PartyDetailVm
{
    ...

    public PersonNameVm PersonNameVm { get { return GetSatelliteVm<PersonNameVm>(); } }
    public HonorificVm HonorificVm { get { return GetSatelliteVm<HonorificVm>(); } }

    // THIS is the problem child I cannot add to the map
   ** public GenderVm GenderVm { get { return GetSatelliteVm<GenderVm>(); } } **

 }

エラー

エラー 82 引数 1: 'Parties.Presentation.ViewModels.PimDetailVms.PersonDetailVms.GenderVm' から 'Core.Presentation.Wpf.ViewModels.MasterDetailVms.DetailVms.SatelliteVms.ISatelliteVm' に変換できません

ビリーのために編集

ビリー、SatelliteVm は ISatelliteVm を実装する単なる基本クラスです。Person は Party のサブクラスで、Gender は列挙型です。

public class GenderVm : SatelliteViewModel<Person, Gender>
{
}

問題を解決するように見える GenderVm への変更 (理由はわかりません!)

 public class GenderVm : SatelliteViewModel<Person, Gender>, ISatelliteVm<Party, object>
{

    Party ISatelliteVm<Party, object>.ParentModel { get { return base.ParentModel; } }

    object ISatelliteVm<Party, object>.Model { get { return base.Model; } }
}
4

1 に答える 1

2

ドキュメントを参照してください:

ジェネリック インターフェイスの差異は、参照型に対してのみサポートされています。値の型は分散をサポートしていません。たとえば、整数は値型で表されるため、IEnumerable<int>を暗黙的に に変換することはできません。IEnumerable<object>

これはあなたの問題に対処する必要があります。

たぶんGender、クラスに変更する必要がありますか?

于 2012-09-30T17:41:16.483 に答える